/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Semantic/Semantics/SwitchTests.cs
3 708 строк
129 KB
Jared Parsons
Move net451 test assets to net461 (#74766)
17 авг 2024, 19:21
Не верифицирован
17 авг 2024, 19:21
75b26a2
Код
Авторство
О чём код?
// 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. #nullable disable using System.Linq; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; using System.Collections.Generic; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { /// <summary> /// Tests related to binding switch statement. /// </summary> public class SwitchTests : CompilingTestBase { #region "Common Error Tests" [WorkItem(543285, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543285")] [Fact] public void NoCS0029ForUsedLocalConstInSwitch() { var source = @" class Program { static void Main(string[] args) { const string ss = ""A""; switch (args[0]) { case ss: break; } } } "; CreateCompilation(source).VerifyDiagnostics(); } [Fact] public void CS0037_NullCaseLabel_NonNullableSwitchExpression() { var text = @"using System; public class Test { enum eTypes { kFirst, kSecond, kThird, }; public static int Main(string [] args) { int ret = 0; ret = DoEnum(); return(ret); } private static int DoEnum() { int ret = 0; eTypes e = eTypes.kSecond; switch (e) { case null: break; default: ret = 1; break; } Console.WriteLine(ret); return(ret); } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (23,18): error CS0037: Cannot convert null to 'Test.eTypes' because it is a non-nullable value type // case null: Diagnostic(ErrorCode.ERR_ValueCantBeNull, "null").WithArguments("Test.eTypes").WithLocation(23, 18) ); CreateCompilation(text).VerifyDiagnostics( // (23,18): error CS0037: Cannot convert null to 'Test.eTypes' because it is a non-nullable value type // case null: Diagnostic(ErrorCode.ERR_ValueCantBeNull, "null").WithArguments("Test.eTypes").WithLocation(23, 18) ); } [WorkItem(542773, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542773")] [Fact] public void CS0119_TypeUsedAsSwitchExpression() { var text = @"class A { public static void Main() { } void goo(color color1) { switch (color) { default: break; } } } enum @color { blue, green }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (7,17): error CS0119: 'color' is a type, which is not valid in the given context // switch (color) Diagnostic(ErrorCode.ERR_BadSKunknown, "color").WithArguments("color", "type").WithLocation(7, 17) ); CreateCompilation(text).VerifyDiagnostics( // (7,17): error CS0119: 'color' is a type, which is not valid in the given context // switch (color) Diagnostic(ErrorCode.ERR_BadSKunknown, "color").WithArguments("color", "type").WithLocation(7, 17) ); } [Fact] public void CS0150_NonConstantSwitchCase() { var text = @" public class Test { public static int Main(string [] args) { int ret = 1; int value = 23; int test = 1; switch (value) { case test: ret = 1; break; default: ret = 1; break; } return(ret); } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (11,18): error CS9135: A constant value of type 'int' is expected // case test: Diagnostic(ErrorCode.ERR_ConstantValueOfTypeExpected, "test").WithArguments("int").WithLocation(11, 18) ); CreateCompilation(text).VerifyDiagnostics( // (11,18): error CS9135: A constant value of type 'int' is expected // case test: Diagnostic(ErrorCode.ERR_ConstantValueOfTypeExpected, "test").WithArguments("int").WithLocation(11, 18) ); } [Fact] public void CS0152_DuplicateCaseLabel() { var text = @" public class A { public static int Main() { int i = 0; switch (i) { case 1: break; case 1: break; // CS0152 } return 1; } public void goo(char c) { switch (c) { case 'f': break; case 'f': // CS0152 break; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (11,13): error CS0152: The switch statement contains multiple cases with the label value '1' // case 1: break; // CS0152 Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 1:").WithArguments("1").WithLocation(11, 13), // (23,13): error CS0152: The switch statement contains multiple cases with the label value 'f' // case 'f': // CS0152 Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 'f':").WithArguments("f").WithLocation(23, 13) ); CreateCompilation(text).VerifyDiagnostics( // (11,13): error CS0152: The switch statement contains multiple cases with the label value '1' // case 1: break; // CS0152 Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 1:").WithArguments("1").WithLocation(11, 13), // (23,13): error CS0152: The switch statement contains multiple cases with the label value 'f' // case 'f': // CS0152 Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 'f':").WithArguments("f").WithLocation(23, 13) ); } [Fact] public void CS0152_DuplicateCaseLabelWithDifferentTypes() { var text = @" public class A { public static int Main() { long i = 0; switch (i) { case 1L: break; case 1: break; // CS0152 } return 1; } public void goo(int i) { switch (i) { case 'a': break; case 97: // CS0152 break; } } public void goo2(char i) { switch (i) { case 97.0f: break; case 97.0f: break; case 'a': break; case 97: break; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (11,13): error CS0152: The switch statement contains multiple cases with the label value '1' // case 1: break; // CS0152 Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 1:").WithArguments("1").WithLocation(11, 13), // (23,13): error CS0152: The switch statement contains multiple cases with the label value '97' // case 97: // CS0152 Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 97:").WithArguments("97").WithLocation(23, 13), // (32,18): error CS0266: Cannot implicitly convert type 'float' to 'char'. An explicit conversion exists (are you missing a cast?) // case 97.0f: Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97.0f").WithArguments("float", "char").WithLocation(32, 18), // (34,18): error CS0266: Cannot implicitly convert type 'float' to 'char'. An explicit conversion exists (are you missing a cast?) // case 97.0f: Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97.0f").WithArguments("float", "char").WithLocation(34, 18), // (34,13): error CS0152: The switch statement contains multiple cases with the label value 'a' // case 97.0f: Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 97.0f:").WithArguments("a").WithLocation(34, 13), // (36,13): error CS0152: The switch statement contains multiple cases with the label value 'a' // case 'a': Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 'a':").WithArguments("a").WithLocation(36, 13), // (38,18): error CS0266: Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?) // case 97: Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97").WithArguments("int", "char").WithLocation(38, 18), // (38,13): error CS0152: The switch statement contains multiple cases with the label value 'a' // case 97: Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 97:").WithArguments("a").WithLocation(38, 13) ); CreateCompilation(text).VerifyDiagnostics( // (11,13): error CS0152: The switch statement contains multiple cases with the label value '1' // case 1: break; // CS0152 Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 1:").WithArguments("1").WithLocation(11, 13), // (23,13): error CS0152: The switch statement contains multiple cases with the label value '97' // case 97: // CS0152 Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 97:").WithArguments("97").WithLocation(23, 13), // (32,18): error CS0266: Cannot implicitly convert type 'float' to 'char'. An explicit conversion exists (are you missing a cast?) // case 97.0f: Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97.0f").WithArguments("float", "char").WithLocation(32, 18), // (34,18): error CS0266: Cannot implicitly convert type 'float' to 'char'. An explicit conversion exists (are you missing a cast?) // case 97.0f: Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97.0f").WithArguments("float", "char").WithLocation(34, 18), // (34,13): error CS0152: The switch statement contains multiple cases with the label value 'a' // case 97.0f: Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 97.0f:").WithArguments("a").WithLocation(34, 13), // (36,13): error CS0152: The switch statement contains multiple cases with the label value 'a' // case 'a': Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 'a':").WithArguments("a").WithLocation(36, 13), // (38,18): error CS0266: Cannot implicitly convert type 'int' to 'char'. An explicit conversion exists (are you missing a cast?) // case 97: Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "97").WithArguments("int", "char").WithLocation(38, 18), // (38,13): error CS0152: The switch statement contains multiple cases with the label value 'a' // case 97: Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 97:").WithArguments("a").WithLocation(38, 13) ); } [Fact] public void CS0152_DuplicateDefaultLabel() { var text = @" public class TestClass { public static void Main() { int i = 10; switch (i) { default: break; case 0: break; case 1: break; default: //CS0152 break; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (15,13): error CS0152: The switch statement contains multiple cases with the label value 'default' // default: //CS0152 Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "default:").WithArguments("default").WithLocation(15, 13) ); CreateCompilation(text).VerifyDiagnostics( // (15,13): error CS0152: The switch statement contains multiple cases with the label value 'default' // default: //CS0152 Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "default:").WithArguments("default").WithLocation(15, 13) ); } [Fact] public void CS0152_DuplicateDefaultLabel2() { var text = @" public class TestClass { public static void Main() { int i = 10; switch (i) { default: break; case (default): break; case 1: break; default: //CS0152 break; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular7_1).VerifyDiagnostics( // (11,19): error CS8505: A default literal 'default' is not valid as a pattern. Use another literal (e.g. '0' or 'null') as appropriate. To match everything, use a discard pattern '_'. // case (default): Diagnostic(ErrorCode.ERR_DefaultPattern, "default").WithLocation(11, 19), // (15,13): error CS0152: The switch statement contains multiple cases with the label value 'default' // default: //CS0152 Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "default:").WithArguments("default").WithLocation(15, 13) ); } [Fact] public void CS0159_NestedSwitchWithInvalidGoto() { var text = @" public class Test { public static int Main(string [] args) { switch (5) { case 5: switch (2) { case 1: goto case 5; } break; } return(0); } }"; // CONSIDER: Cascading diagnostics should be disabled in flow analysis? CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (10,17): error CS0159: No such label 'case 5:' within the scope of the goto statement // goto case 5; Diagnostic(ErrorCode.ERR_LabelNotFound, "goto case 5;").WithArguments("case 5:").WithLocation(10, 17), // (10,17): warning CS0162: Unreachable code detected // goto case 5; Diagnostic(ErrorCode.WRN_UnreachableCode, "goto").WithLocation(10, 17) ); CreateCompilation(text).VerifyDiagnostics( // (10,17): error CS0159: No such label 'case 5:' within the scope of the goto statement // goto case 5; Diagnostic(ErrorCode.ERR_LabelNotFound, "goto case 5;").WithArguments("case 5:").WithLocation(10, 17), // (10,17): warning CS0162: Unreachable code detected // goto case 5; Diagnostic(ErrorCode.WRN_UnreachableCode, "goto").WithLocation(10, 17) ); } [Fact] public void CS0166_InvalidSwitchGoverningType() { var text = @" public class Test { public static int Main(string [] args) { double test = 1.1; int ret = 1; switch (test) { case 1: ret = 1; break; default: ret = 1; break; } return(ret); } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (9,17): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch (test) { Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "test").WithLocation(9, 17) ); CreateCompilation(text).VerifyDiagnostics( ); } [Fact] public void CS0166_InvalidSwitchExpression_Null() { var text = @" class T { public static void Main() { switch(null) { default: break; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (6,16): error CS8119: The switch expression must be a value; found <null>. // switch(null) Diagnostic(ErrorCode.ERR_SwitchExpressionValueExpected, "null").WithArguments("<null>").WithLocation(6, 16) ); CreateCompilation(text).VerifyDiagnostics( // (6,16): error CS8119: The switch expression must be a value; found <null>. // switch(null) Diagnostic(ErrorCode.ERR_SwitchExpressionValueExpected, "null").WithArguments("<null>").WithLocation(6, 16) ); } [Fact] public void CS0166_InvalidSwitchExpression_Void() { var text = @" class T { public static void Main() { switch(M()) { default: break; } } public static void M() { } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (6,16): error CS8119: The switch expression must be a value; found void. // switch(M()) Diagnostic(ErrorCode.ERR_SwitchExpressionValueExpected, "M()").WithArguments("void").WithLocation(6, 16) ); CreateCompilation(text).VerifyDiagnostics( // (6,16): error CS8119: The switch expression must be a value; found void. // switch(M()) Diagnostic(ErrorCode.ERR_SwitchExpressionValueExpected, "M()").WithArguments("void").WithLocation(6, 16) ); } [Fact] public void CS0166_InvalidSwitchExpression_MethodGroup() { var text = @" class T { public static void Main() { switch(M) { default: break; } } public static void M() { } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (6,16): error CS8119: The switch expression must be a value; found method group // switch(M) Diagnostic(ErrorCode.ERR_SwitchExpressionValueExpected, "M").WithArguments("method group").WithLocation(6, 16) ); CreateCompilation(text).VerifyDiagnostics( // (6,16): error CS8119: The switch expression must be a value; found method group. // switch(M) Diagnostic(ErrorCode.ERR_SwitchExpressionValueExpected, "M").WithArguments("method group").WithLocation(6, 16) ); } [Fact] public void CS0166_InvalidSwitchExpression_Lambda() { var text = @" class T { public static void Main() { switch(() => {}) { default: break; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (6,16): error CS8119: The switch expression must be a value; found lambda expression // switch(() => {}) Diagnostic(ErrorCode.ERR_SwitchExpressionValueExpected, "() => {}").WithArguments("lambda expression").WithLocation(6, 16)); CreateCompilation(text).VerifyDiagnostics( // (6,16): error CS8119: The switch expression must be a value; found lambda expression // switch(() => {}) Diagnostic(ErrorCode.ERR_SwitchExpressionValueExpected, "() => {}").WithArguments("lambda expression").WithLocation(6, 16)); } [Fact] public void CS0166_AggregateTypeWithMultipleImplicitConversions_01() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" class Conv { public static implicit operator int (Conv C) { return 1; } public static implicit operator int? (Conv C) { return null; } public static int Main() { Conv C = new Conv(); switch(C) { default: System.Console.WriteLine(""Fail""); return 1; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (17,16): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(C) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "C").WithLocation(17, 16)); CreateCompilation(text).VerifyDiagnostics(); } [Fact] public void CS0166_AggregateTypeWithMultipleImplicitConversions_02() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" class Conv { public static implicit operator int (Conv C) { return 1; } public static implicit operator char? (Conv C) { return null; } public static int Main() { Conv C = new Conv(); switch(C) { default: System.Console.WriteLine(""Fail""); return 1; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (17,16): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(C) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "C").WithLocation(17, 16) ); CreateCompilation(text).VerifyDiagnostics( ); } [Fact] public void CS0166_AggregateTypeWithMultipleImplicitConversions_03() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" struct Conv { public static implicit operator int (Conv C) { return 1; } public static implicit operator int? (Conv? C) { return null; } public static int Main() { Conv C = new Conv(); switch(C) { default: System.Console.WriteLine(""Fail""); return 0; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (17,10): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(C) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "C").WithLocation(17, 16) ); CreateCompilation(text).VerifyDiagnostics( ); } [Fact] public void CS0166_AggregateTypeWithMultipleImplicitConversions_04() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" struct Conv { public static implicit operator int (Conv C) { return 1; } public static implicit operator int? (Conv? C) { return null; } public static int Main() { Conv C = new Conv(); switch(C) { default: System.Console.WriteLine(""Fail""); break; } Conv? D = new Conv(); switch(D) { default: System.Console.WriteLine(""Fail""); return 0; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (17,16): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(C) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "C").WithLocation(17, 16) ); CreateCompilation(text).VerifyDiagnostics( ); } [Fact] public void CS0166_AggregateTypeWithMultipleImplicitConversions_05() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" struct Conv { public static implicit operator int(Conv C) { return 1; } public static implicit operator int?(Conv C) { return 1; } public static implicit operator int(Conv? C) { return 1; } public static implicit operator int?(Conv? C) { return 0; } public static int Main() { Conv C = new Conv(); switch(C) { default: System.Console.WriteLine(""Fail""); break; } return 0; } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (27,16): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(C) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "C").WithLocation(27, 16)); CreateCompilation(text).VerifyDiagnostics( ); } [Fact] public void CS0166_AggregateTypeWithMultipleImplicitConversions_06() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" struct Conv { public static implicit operator int(Conv C) { return 1; } public static implicit operator int?(Conv C) { return 1; } public static implicit operator int(Conv? C) { return 1; } public static implicit operator int?(Conv? C) { return 0; } public static int Main() { Conv? C = new Conv(); switch(C) { default: System.Console.WriteLine(""Fail""); break; } return 0; } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (27,10): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(C) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "C").WithLocation(27, 16) ); CreateCompilation(text).VerifyDiagnostics( ); } [Fact] public void CS0166_AggregateTypeWithMultipleImplicitConversions_07() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. // Native compiler allows the below code to compile // even though there are two user-defined implicit conversions: // 1) To int type (applicable in normal form): public static implicit operator int (Conv? C2) // 2) To int? type (applicable in lifted form): public static implicit operator int (Conv C) // // Here we deliberately violate the specification and allow the conversion, for backwards compat. var text = @" struct Conv { public static implicit operator int (Conv C) { return 1; } public static implicit operator int (Conv? C2) { return 0; } public static int Main() { Conv? D = new Conv(); switch(D) { case 1: System.Console.WriteLine(""Fail""); return 1; case 0: System.Console.WriteLine(""Pass""); return 0; default: System.Console.WriteLine(""Fail""); return 1; } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics(); CreateCompilation(text).VerifyDiagnostics(); } [Fact] public void CS0166_AggregateTypeWithNoValidImplicitConversions_01() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" class Conv { // bool type is not valid public static implicit operator bool (Conv C) { return false; } public static int Main() { Conv C = new Conv(); switch(C) { default: System.Console.WriteLine(""Fail""); return 1; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (13,16): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(C) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "C").WithLocation(13, 16) ); CreateCompilation(text).VerifyDiagnostics( ); } [Fact] public void CS0166_AggregateTypeWithNoValidImplicitConversions_02() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" enum X { F = 0 } class Conv { // enum type is not valid public static implicit operator X (Conv C) { return X.F; } public static int Main() { Conv C = new Conv(); switch(C) { default: System.Console.WriteLine(""Fail""); return 1; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (14,16): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(C) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "C").WithLocation(14, 16) ); CreateCompilation(text).VerifyDiagnostics( ); } [Fact] public void CS0533_AggregateTypeWithInvalidObjectTypeConversion() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" class Conv { // object type is not valid public static implicit operator object(Conv C) { return null; } public static implicit operator int(Conv C) { return 1; } public static int Main() { Conv C = new Conv(); switch(C) { default: System.Console.WriteLine(""Fail""); return 1; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (5,37): error CS0553: 'Conv.implicit operator object(Conv)': user-defined conversions to or from a base type are not allowed // public static implicit operator object(Conv C) Diagnostic(ErrorCode.ERR_ConversionWithBase, "object").WithArguments("Conv.implicit operator object(Conv)").WithLocation(5, 37)); CreateCompilation(text).VerifyDiagnostics( // (5,37): error CS0553: 'Conv.implicit operator object(Conv)': user-defined conversions to or from a base type are not allowed // public static implicit operator object(Conv C) Diagnostic(ErrorCode.ERR_ConversionWithBase, "object").WithArguments("Conv.implicit operator object(Conv)").WithLocation(5, 37)); } [Fact] public void CS0166_SwitchBlockDiagnosticsAreReported() { var text = @" class C { static void M(object o) { switch (o) { case (1+(o.GetType().Name.Length)): M(); break; case 0: case 0: break; } } static object F(int i) { return null; } static void Main() { } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (6,17): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type in C# 6 and earlier. // switch (o) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "o").WithLocation(6, 17), // (8,19): error CS0150: A constant value is expected // case (1+(o.GetType().Name.Length)): Diagnostic(ErrorCode.ERR_ConstantExpected, "1+(o.GetType().Name.Length)").WithLocation(8, 19), // (9,17): error CS7036: There is no argument given that corresponds to the required parameter 'o' of 'C.M(object)' // M(); Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("o", "C.M(object)").WithLocation(9, 17), // (12,13): error CS0152: The switch statement contains multiple cases with the label value '0' // case 0: Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 0:").WithArguments("0").WithLocation(12, 13) ); CreateCompilation(text).VerifyDiagnostics( // (8,19): error CS0150: A constant value is expected // case (1+(o.GetType().Name.Length)): Diagnostic(ErrorCode.ERR_ConstantExpected, "1+(o.GetType().Name.Length)").WithLocation(8, 19), // (9,17): error CS7036: There is no argument given that corresponds to the required parameter 'o' of 'C.M(object)' // M(); Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("o", "C.M(object)").WithLocation(9, 17), // (12,13): error CS0152: The switch statement contains multiple cases with the label value '0' // case 0: Diagnostic(ErrorCode.ERR_DuplicateCaseLabel, "case 0:").WithArguments("0").WithLocation(12, 13) ); } [Fact] public void CS0266_CaseLabelWithNoImplicitConversionToSwitchGoverningType() { var text = @" public class Test { public static int Main(string [] args) { int i = 5; switch (i) { case 1.2f: return 1; } return 0; } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (10,12): error CS0266: Cannot implicitly convert type 'float' to 'int'. An explicit conversion exists (are you missing a cast?) // case 1.2f: Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1.2f").WithArguments("float", "int").WithLocation(10, 12) ); CreateCompilation(text).VerifyDiagnostics( // (10,12): error CS0266: Cannot implicitly convert type 'float' to 'int'. An explicit conversion exists (are you missing a cast?) // case 1.2f: Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1.2f").WithArguments("float", "int").WithLocation(10, 12) ); } [Fact, WorkItem(546812, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546812")] public void Bug16878() { var text = @" class Program { public static void Main() { int x = 0; switch(x) { #pragma warning disable 6500 case 0: break; #pragma warning restore 6500 } } } "; var comp = CompileAndVerify(text, expectedOutput: ""); // Previous versions of the compiler used to report a warning (CS1691) // whenever an unrecognized warning code was supplied in a #pragma directive. // We no longer generate a warning in such cases. comp.VerifyDiagnostics(); } [Fact] public void MultipleLabelsWithBadConstantValues() { var source = @" class Program { enum E { V1 = 1000, V2 = 1001 } public static void Main() { } public static void Test(E x) { switch (x) { case E.V1: case E.V2: default: break; } } }"; var syntaxTree = SyntaxFactory.ParseSyntaxTree(source); // Intentionally not passing any references here to ensure System.Int32 is // unresolvable and hence the constant values in the enum "E" will all be // created as ConstantValue.Bad var comp = CreateEmptyCompilation(new[] { syntaxTree }, references: null); var semanticModel = comp.GetSemanticModel(syntaxTree); var node = syntaxTree.GetRoot().DescendantNodes().First(x => x.IsKind(SyntaxKind.SimpleMemberAccessExpression)); // Ensure the model can still bind without throwing when multiple labels values // have duplicate constants (ConstantValue.Bad). var symbolInfo = semanticModel.GetSymbolInfo(node); Assert.NotEqual(default, symbolInfo); } #endregion #region "Switch Governing Type with Implicit User Defined Conversion Tests" [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_01() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @"using System; public class Test { public static implicit operator int(Test val) { return 1; } public static implicit operator float(Test val2) { return 2.1f; } public static int Main() { Test t = new Test(); switch (t) { case 1: Console.WriteLine(0); return 0; default: Console.WriteLine(1); return 1; } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics(); CreateCompilation(text).VerifyDiagnostics(); } [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_02() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" class X {} class Conv { public static implicit operator int (Conv C) { return 1; } public static implicit operator X (Conv C2) { return new X(); } public static int Main() { Conv C = new Conv(); switch(C) { case 1: System.Console.WriteLine(""Pass""); return 0; default: System.Console.WriteLine(""Fail""); return 1; } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics(); CreateCompilation(text).VerifyDiagnostics(); } [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_03() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" enum X { F = 0 } class Conv { // only valid operator public static implicit operator int (Conv C) { return 1; } // bool type is not valid public static implicit operator bool (Conv C2) { return false; } // enum type is not valid public static implicit operator X (Conv C3) { return X.F; } public static int Main() { Conv C = new Conv(); switch(C) { case 1: System.Console.WriteLine(""Pass""); return 0; default: System.Console.WriteLine(""Fail""); return 1; } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics(); CreateCompilation(text).VerifyDiagnostics(); } [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_04() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" struct Conv { public static implicit operator int (Conv C) { return 1; } public static implicit operator int? (Conv? C2) { return null; } public static int Main() { Conv? D = new Conv(); switch(D) { case 1: System.Console.WriteLine(""Fail""); return 1; case null: System.Console.WriteLine(""Pass""); return 0; default: System.Console.WriteLine(""Fail""); return 1; } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics(); CreateCompilation(text).VerifyDiagnostics(); } [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_05() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" struct Conv { public static implicit operator int (Conv C) { return 1; } public static int Main() { Conv? C = new Conv(); switch(C) { case 1: System.Console.WriteLine(""Pass""); return 0; case null: System.Console.WriteLine(""Fail""); return 1; default: System.Console.WriteLine(""Fail""); return 1; } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics(); CreateCompilation(text).VerifyDiagnostics(); } [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_06() { // Exactly ONE user-defined implicit conversion (6.4) must exist from the type of // the switch expression to one of the following possible governing types: sbyte, byte, short, // ushort, int, uint, long, ulong, char, string. If no such implicit conversion exists, or if // more than one such implicit conversion exists, a compile-time error occurs. var text = @" struct Conv { public static implicit operator int (Conv C) { return 1; } public static implicit operator int? (Conv? C) { return null; } public static int Main() { Conv? C = new Conv(); switch(C) { case null: System.Console.WriteLine(""Pass""); return 0; case 1: System.Console.WriteLine(""Fail""); return 0; default: System.Console.WriteLine(""Fail""); return 0; } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics(); CreateCompilation(text).VerifyDiagnostics(); } [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_TypeParameter() { var text = @"class A1 { } class A2 { public static implicit operator int(A2 a) { return 0; } } class B1<T> where T : A1 { internal T F() { return null; } } class B2<T> where T : A2 { internal T F() { return null; } } class C { static void M<T>(B1<T> b1) where T : A1 { switch (b1.F()) { default: break; } } static void M<T>(B2<T> b2) where T : A2 { switch (b2.F()) { default: break; } } }"; // Note: Dev10 also reports CS0151 for "b2.F()", although // there is an implicit conversion from A2 to int. CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (20,17): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "b1.F()").WithLocation(20, 17) ); CreateCompilation(text).VerifyDiagnostics( ); } [WorkItem(543673, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543673")] [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_11564_2_1() { // Dev10 behavior: 1st switch expression is an ambiguous user defined conversion // Dev10 behavior: 2nd switch expression is an ambiguous user defined conversion var text = @"using System; struct A { public static implicit operator int?(A a) { Console.WriteLine(""0""); return 0; } public static implicit operator int(A a) { Console.WriteLine(""1""); return 0; } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } A a = new A(); switch(a) { default: break; } } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (28,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(a) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "a").WithLocation(28, 20) ); CreateCompilation(text).VerifyDiagnostics( ); } [WorkItem(543673, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543673")] [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_11564_2_2() { // Dev10 behavior: 1st switch expression is an ambiguous user defined conversion // Dev10 behavior: 2nd switch expression is an ambiguous user defined conversion var text = @"using System; struct A { public static implicit operator int?(A? a) { Console.WriteLine(""0""); return 0; } public static implicit operator int(A? a) { Console.WriteLine(""1""); return 0; } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } A a = new A(); switch(a) { default: break; } } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (22,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(aNullable) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "aNullable"), // (28,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(a) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "a")); CreateCompilation(text).VerifyDiagnostics( ); } [WorkItem(543673, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543673")] [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_11564_2_3() { // 2nd switch expression is an ambiguous user defined conversion (both applicable in non-lifted form) var text = @"using System; struct A { public static implicit operator int?(A? a) { Console.WriteLine(""0""); return 0; } public static implicit operator int(A a) { Console.WriteLine(""1""); return 0; } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } A a = new A(); switch(a) { default: break; } } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (28,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(a) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "a") ); CreateCompilation(text).VerifyDiagnostics( ); } [WorkItem(543673, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543673")] [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_11564_2_4() { // 2nd switch expression is an ambiguous user defined conversion (both applicable in non-lifted form) var text = @"using System; struct A { public static implicit operator int?(A a) { Console.WriteLine(""0""); return 0; } public static implicit operator int(A? a) { Console.WriteLine(""1""); return 0; } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } A a = new A(); switch(a) { default: break; } } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (28,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(a) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "a") ); CreateCompilation(text).VerifyDiagnostics( ); } [WorkItem(543673, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543673")] [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_11564_2_5() { // 2nd switch expression is an ambiguous user defined conversion var text = @"using System; struct A { public static implicit operator int(A a) { Console.WriteLine(""0""); return 0; } public static implicit operator int(A? a) { Console.WriteLine(""1""); return 0; } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } A a = new A(); switch(a) { default: break; } } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (28,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(a) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "a").WithLocation(28, 20) ); CreateCompilation(text).VerifyDiagnostics( ); } [WorkItem(543673, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543673")] [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_11564_2_6() { // 2nd switch expression is an ambiguous user defined conversion var text = @"using System; struct A { public static implicit operator int?(A a) { Console.WriteLine(""0""); return 0; } public static implicit operator int?(A? a) { Console.WriteLine(""1""); return 0; } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } A a = new A(); switch(a) { default: break; } } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (28,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(a) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "a").WithLocation(28, 20) ); CreateCompilation(text).VerifyDiagnostics( ); } [WorkItem(543673, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543673")] [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_11564_3_1() { // 2nd switch expression is an ambiguous user defined conversion var text = @"using System; struct A { public static implicit operator int(A a) { Console.WriteLine(""0""); return 0; } public static implicit operator int(A? a) { Console.WriteLine(""1""); return 0; } public static implicit operator int?(A a) { Console.WriteLine(""2""); return 0; } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } A a = new A(); switch(a) { default: break; } } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (34,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type in C# 6 and earlier. // switch(a) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "a").WithLocation(34, 20) ); CreateCompilation(text).VerifyDiagnostics( ); } [WorkItem(543673, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543673")] [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_11564_3_2() { // 1st switch expression is an ambiguous user defined conversion // 2nd switch expression is an ambiguous user defined conversion var text = @"using System; struct A { public static implicit operator int(A a) { Console.WriteLine(""0""); return 0; } public static implicit operator int(A? a) { Console.WriteLine(""1""); return 0; } public static implicit operator int?(A? a) { Console.WriteLine(""2""); return 0; } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } A a = new A(); switch(a) { default: break; } } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (28,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(aNullable) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "aNullable"), // (34,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(a) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "a") ); CreateCompilation(text).VerifyDiagnostics( ); } [WorkItem(543673, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543673")] [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_11564_3_3() { // 2nd switch expression is an ambiguous user defined conversion var text = @"using System; struct A { public static implicit operator int?(A a) { Console.WriteLine(""0""); return 0; } public static implicit operator int?(A? a) { Console.WriteLine(""1""); return 0; } public static implicit operator int(A a) { Console.WriteLine(""2""); return 0; } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } A a = new A(); switch(a) { default: break; } } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (34,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(a) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "a") ); CreateCompilation(text).VerifyDiagnostics( ); } [WorkItem(543673, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543673")] [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_11564_3_4() { // 1st switch expression is an ambiguous user defined conversion // 2nd switch expression is an ambiguous user defined conversion var text = @"using System; struct A { public static implicit operator int?(A a) { Console.WriteLine(""0""); return 0; } public static implicit operator int?(A? a) { Console.WriteLine(""1""); return 0; } public static implicit operator int(A? a) { Console.WriteLine(""2""); return 0; } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } A a = new A(); switch(a) { default: break; } } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (28,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(aNullable) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "aNullable"), // (34,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(a) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "a") ); CreateCompilation(text).VerifyDiagnostics( ); } [WorkItem(543673, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543673")] [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_11564_4_1() { // 1st switch expression is an ambiguous user defined conversion // 2nd switch expression is an ambiguous user defined conversion var text = @"using System; struct A { public static implicit operator int?(A a) { Console.WriteLine(""0""); return 0; } public static implicit operator int?(A? a) { Console.WriteLine(""1""); return 0; } public static implicit operator int(A? a) { Console.WriteLine(""2""); return 0; } public static implicit operator int(A a) { Console.WriteLine(""3""); return 0; } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } A a = new A(); switch(a) { default: break; } } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (34,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(aNullable) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "aNullable"), // (40,20): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch(a) Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "a") ); CreateCompilation(text).VerifyDiagnostics( ); } [WorkItem(4344, "https://github.com/dotnet/roslyn/issues/4344")] [Fact] public void ImplicitNullableUserDefinedConversionToSwitchGoverningTypeString01() { var text = @"using System; struct A { public static implicit operator string(A a1) { Console.WriteLine(nameof(a1)); return nameof(a1); } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } } } } "; CompileAndVerify(text, parseOptions: TestOptions.Regular6, expectedOutput: "a1"); CompileAndVerify(text, expectedOutput: "a1"); } [WorkItem(4344, "https://github.com/dotnet/roslyn/issues/4344")] [Fact] public void ImplicitNullableUserDefinedConversionToSwitchGoverningTypeString02() { var text = @"using System; struct A { public static implicit operator string(A a1) { Console.WriteLine(nameof(a1)); return nameof(a1); } public static implicit operator string(A? a2) { Console.WriteLine(nameof(a2)); return nameof(a2); } class B { static void Main() { A? aNullable = new A(); switch(aNullable) { default: break; } } } } "; CompileAndVerify(text, parseOptions: TestOptions.Regular6, expectedOutput: "a2"); CompileAndVerify(text, expectedOutput: "a2"); } [WorkItem(4344, "https://github.com/dotnet/roslyn/issues/4344")] [Fact] public void ImplicitNullableUserDefinedConversionToSwitchGoverningTypeInt() { var text = @"using System; class Program { static void Main(string[] args) { M(default(X)); M(null); } static void M(X? x) { switch (x) { case null: Console.WriteLine(""null""); break; case 1: Console.WriteLine(1); break; } } } struct X { public static implicit operator int? (X x) { return 1; } }"; CompileAndVerify(text, parseOptions: TestOptions.Regular6, expectedOutput: @"1 null"); CompileAndVerify(text, expectedOutput: @"1 null"); } [WorkItem(4344, "https://github.com/dotnet/roslyn/issues/4344")] [Fact] public void ImplicitUserDefinedConversionToSwitchGoverningType_42() { var text = @"using System; struct A { public static implicit operator int?(A a) { Console.WriteLine(""0""); return 0; } public static implicit operator string (A? a) { Console.WriteLine(""1""); return """"; } class B { static void Main() { A? aNullable = new A(); switch (aNullable) // only A?->string is applicable in non-lifted form { case """": default: break; } A a = new A(); switch (a) // both operators applicable in non-lifted form -> error { default: break; } } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (29,21): error CS0151: A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type // switch (a) // both operators applicable in non-lifted form -> error Diagnostic(ErrorCode.ERR_V6SwitchGoverningTypeValueExpected, "a").WithLocation(29, 21) ); CreateCompilation(text).VerifyDiagnostics( ); } #endregion #region "Control Flow analysis: CS8070 Switch fall out error tests" [Fact] public void CS8070_SwitchFallOut_DefaultLabel() { var text = @"using System; class Test { public static void DoTest(int i) { switch (i) { case 1: Console.WriteLine(i); break; case 2: Console.WriteLine(i); break; default: // CS8070 Console.WriteLine(i); } } public static int Main() { return 1; } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (14,13): error CS8070: Control cannot fall out of switch from final case label ('default:') // default: // CS8070 Diagnostic(ErrorCode.ERR_SwitchFallOut, "default:").WithArguments("default:").WithLocation(14, 13) ); CreateCompilation(text).VerifyDiagnostics( // (14,13): error CS8070: Control cannot fall out of switch from final case label ('default:') // default: // CS8070 Diagnostic(ErrorCode.ERR_SwitchFallOut, "default:").WithArguments("default:").WithLocation(14, 13) ); } [Fact] public void CS8070_SwitchFallOutError() { var text = @" namespace Test { public class Program { static int Main() { int? i = 10; switch ((int)i) { case 10: i++; break; case 11: ; } return -1; } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (15,17): error CS8070: Control cannot fall out of switch from final case label ('case 11') // case 11: Diagnostic(ErrorCode.ERR_SwitchFallOut, "case 11:").WithArguments("case 11:").WithLocation(15, 17) ); CreateCompilation(text).VerifyDiagnostics( // (15,17): error CS8070: Control cannot fall out of switch from final case label ('case 11') // case 11: Diagnostic(ErrorCode.ERR_SwitchFallOut, "case 11:").WithArguments("case 11:").WithLocation(15, 17) ); } [Fact] public void CS8070_ErrorsInMultipleSwitchStmtsAreReported() { var text = @" namespace Test { public class Program { static int Main() { int? i = 10; switch ((int)i) { case 10: i++; break; case 11: ; } int j = 5; goto LDone; LDone: switch (j) { case 5: } int? k = 10; switch ((int)k) { case 10: break; default: ; } return -1; } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (15,17): error CS8070: Control cannot fall out of switch from final case label ('case 11:') // case 11: Diagnostic(ErrorCode.ERR_SwitchFallOut, "case 11:").WithArguments("case 11:").WithLocation(15, 17), // (24,17): error CS8070: Control cannot fall out of switch from final case label ('case 5:') // case 5: Diagnostic(ErrorCode.ERR_SwitchFallOut, "case 5:").WithArguments("case 5:").WithLocation(24, 17), // (32,17): error CS8070: Control cannot fall out of switch from final case label ('default:') // default: Diagnostic(ErrorCode.ERR_SwitchFallOut, "default:").WithArguments("default:").WithLocation(32, 17) ); CreateCompilation(text).VerifyDiagnostics( // (15,17): error CS8070: Control cannot fall out of switch from final case label ('case 11:') // case 11: Diagnostic(ErrorCode.ERR_SwitchFallOut, "case 11:").WithArguments("case 11:").WithLocation(15, 17), // (24,17): error CS8070: Control cannot fall out of switch from final case label ('case 5:') // case 5: Diagnostic(ErrorCode.ERR_SwitchFallOut, "case 5:").WithArguments("case 5:").WithLocation(24, 17), // (32,17): error CS8070: Control cannot fall out of switch from final case label ('default:') // default: Diagnostic(ErrorCode.ERR_SwitchFallOut, "default:").WithArguments("default:").WithLocation(32, 17) ); } [Fact] public void SwitchFallOut_Script() { var source = @"using System; switch (1) { default: Console.WriteLine(1); case 2: Console.WriteLine(2); }"; CreateCompilationWithMscorlib461(source, references: new[] { SystemCoreRef }, parseOptions: TestOptions.Script).VerifyDiagnostics( // (4,5): error CS0163: Control cannot fall through from one case label ('default:') to another // default: Diagnostic(ErrorCode.ERR_SwitchFallThrough, "default:").WithArguments("default:").WithLocation(4, 5), // (7,9): warning CS0162: Unreachable code detected // Console.WriteLine(2); Diagnostic(ErrorCode.WRN_UnreachableCode, "Console").WithLocation(7, 9) ); } [Fact] public void SwitchFallOut_Submission() { var source = @"using System; switch (1) { case 1: Console.WriteLine(1); default: Console.WriteLine(2); }"; var submission = CSharpCompilation.CreateScriptCompilation( "s0.dll", syntaxTree: SyntaxFactory.ParseSyntaxTree(source, options: TestOptions.Script), references: new[] { MscorlibRef, SystemCoreRef }); submission.VerifyDiagnostics( // (4,5): error CS0163: Control cannot fall through from one case label ('case 1:') to another // case 1: Diagnostic(ErrorCode.ERR_SwitchFallThrough, "case 1:").WithArguments("case 1:").WithLocation(4, 5), // (7,9): warning CS0162: Unreachable code detected // Console.WriteLine(2); Diagnostic(ErrorCode.WRN_UnreachableCode, "Console").WithLocation(7, 9) ); } #endregion # region "Control Flow analysis: CS0163 Switch fall through error tests" [Fact] public void CS0163_SwitchFallThroughError() { var text = @"using System; class Test { public static void DoTest(int i) { switch (i) { case 1: Console.WriteLine(i); break; case 2: // CS0163 Console.WriteLine(i); default: Console.WriteLine(i); break; } } public static int Main() { return 1; } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (11,13): error CS0163: Control cannot fall through from one case label ('case 2:') to another // case 2: // CS0163 Diagnostic(ErrorCode.ERR_SwitchFallThrough, "case 2:").WithArguments("case 2:").WithLocation(11, 13) ); CreateCompilation(text).VerifyDiagnostics( // (11,13): error CS0163: Control cannot fall through from one case label ('case 2:') to another // case 2: // CS0163 Diagnostic(ErrorCode.ERR_SwitchFallThrough, "case 2:").WithArguments("case 2:").WithLocation(11, 13) ); } [Fact] public void CS0163_ErrorsInMultipleSwitchStmtsAreReported() { var text = @" namespace Test { public class Program { static int Main() { int? i = 10; switch ((int)i) { case 10: ; default: break; } int j = 5; goto LDone; LDone: switch (j) { case 5: ; case 7: break; } int? k = 10; switch ((int)k) { case 10: ; case 11: break; } return -1; } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (12,17): error CS0163: Control cannot fall through from one case label ('case 10:') to another // case 10: Diagnostic(ErrorCode.ERR_SwitchFallThrough, "case 10:").WithArguments("case 10:").WithLocation(12, 17), // (23,17): error CS0163: Control cannot fall through from one case label ('case 5:') to another // case 5: Diagnostic(ErrorCode.ERR_SwitchFallThrough, "case 5:").WithArguments("case 5:").WithLocation(23, 17), // (32,17): error CS0163: Control cannot fall through from one case label ('case 10:') to another // case 10: Diagnostic(ErrorCode.ERR_SwitchFallThrough, "case 10:").WithArguments("case 10:").WithLocation(32, 17) ); CreateCompilation(text).VerifyDiagnostics( // (12,17): error CS0163: Control cannot fall through from one case label ('case 10:') to another // case 10: Diagnostic(ErrorCode.ERR_SwitchFallThrough, "case 10:").WithArguments("case 10:").WithLocation(12, 17), // (23,17): error CS0163: Control cannot fall through from one case label ('case 5:') to another // case 5: Diagnostic(ErrorCode.ERR_SwitchFallThrough, "case 5:").WithArguments("case 5:").WithLocation(23, 17), // (32,17): error CS0163: Control cannot fall through from one case label ('case 10:') to another // case 10: Diagnostic(ErrorCode.ERR_SwitchFallThrough, "case 10:").WithArguments("case 10:").WithLocation(32, 17) ); } #endregion #region "Data flow analysis: CS0165 Uninitialized variable error tests" [Fact] public void CS0165_SwitchScopeUnassignedVariable() { var text = @" public class Goo { public Goo() { i = 99; } public void Bar() { i = 0; } public int GetI() { return(i); } int i; } public class Test { public static int Main(string [] args) { int s = 23; switch (s) { case 21: int j = 0; Goo f = new Goo(); j++; break; case 23: int i = 22; j = i; f.Bar(); // unassigned variable f break; } return(1); } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (24,4): error CS0165: Use of unassigned local variable 'f' // f.Bar(); // unassigned variable f Diagnostic(ErrorCode.ERR_UseDefViolation, "f").WithArguments("f").WithLocation(24, 13)); CreateCompilation(text).VerifyDiagnostics( // (24,4): error CS0165: Use of unassigned local variable 'f' // f.Bar(); // unassigned variable f Diagnostic(ErrorCode.ERR_UseDefViolation, "f").WithArguments("f").WithLocation(24, 13)); } [Fact] public void CS0165_UnreachableCasesHaveAssignment() { var text = @"using System; class SwitchTest { public static int Main() { int goo; // unassigned goo switch (3) { case 1: goo = 1; break; case 2: goo = 2; goto case 1; } Console.WriteLine(goo); return 1; } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (10,17): warning CS0162: Unreachable code detected // goo = 1; Diagnostic(ErrorCode.WRN_UnreachableCode, "goo").WithLocation(10, 17), // (13,17): warning CS0162: Unreachable code detected // goo = 2; Diagnostic(ErrorCode.WRN_UnreachableCode, "goo").WithLocation(13, 17), // (17,27): error CS0165: Use of unassigned local variable 'goo' // Console.WriteLine(goo); Diagnostic(ErrorCode.ERR_UseDefViolation, "goo").WithArguments("goo").WithLocation(17, 27)); CreateCompilation(text).VerifyDiagnostics( // (10,17): warning CS0162: Unreachable code detected // goo = 1; Diagnostic(ErrorCode.WRN_UnreachableCode, "goo").WithLocation(10, 17), // (13,17): warning CS0162: Unreachable code detected // goo = 2; Diagnostic(ErrorCode.WRN_UnreachableCode, "goo").WithLocation(13, 17), // (17,27): error CS0165: Use of unassigned local variable 'goo' // Console.WriteLine(goo); Diagnostic(ErrorCode.ERR_UseDefViolation, "goo").WithArguments("goo").WithLocation(17, 27)); } [Fact] public void CS0165_NoAssignmentOnOneControlPath() { var text = @"using System; class SwitchTest { public static int Main() { int i = 3; int goo; // unassigned goo switch (i) { case 1: goto default; mylabel: try { if (i > 0) { break; // goo is not definitely assigned here } throw new System.ApplicationException(); } catch(Exception) { goo = 1; break; } case 2: goto mylabel; case 3: if (true) { goo = 1; goto case 2; } default: goo = 1; break; } Console.WriteLine(goo); // CS0165 return goo; } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (40,27): error CS0165: Use of unassigned local variable 'goo' // Console.WriteLine(goo); // CS0165 Diagnostic(ErrorCode.ERR_UseDefViolation, "goo").WithArguments("goo").WithLocation(40, 27)); CreateCompilation(text).VerifyDiagnostics( // (40,27): error CS0165: Use of unassigned local variable 'goo' // Console.WriteLine(goo); // CS0165 Diagnostic(ErrorCode.ERR_UseDefViolation, "goo").WithArguments("goo").WithLocation(40, 27)); } [Fact, WorkItem(32806, "https://github.com/dotnet/roslyn/issues/32806")] public void TraditionalSwitchIsIncomplete_01() { var text = @" class SwitchTest { static int Main(string[] args) { bool? test = null; switch (test) { case true: return 1; case false: return 0; case null: return -1; } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (4,16): error CS0161: 'SwitchTest.Main(string[])': not all code paths return a value // static int Main(string[] args) Diagnostic(ErrorCode.ERR_ReturnExpected, "Main").WithArguments("SwitchTest.Main(string[])").WithLocation(4, 16) ); CreateCompilation(text, parseOptions: TestOptions.Regular7_3).VerifyDiagnostics( // (4,16): error CS0161: 'SwitchTest.Main(string[])': not all code paths return a value // static int Main(string[] args) Diagnostic(ErrorCode.ERR_ReturnExpected, "Main").WithArguments("SwitchTest.Main(string[])").WithLocation(4, 16) ); CreateCompilation(text, parseOptions: TestOptions.Regular8).VerifyDiagnostics(); } [Fact, WorkItem(32806, "https://github.com/dotnet/roslyn/issues/32806")] public void TraditionalSwitchIsIncomplete_02() { var text = @" class SwitchTest { static int Main(string[] args) { bool? test = null; switch (test) { case true when true: return 1; case false: return 0; case null: return -1; } } } "; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (10,13): error CS8059: Feature 'pattern matching' is not available in C# 6. Please use language version 7.0 or greater. // case true when true: Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion6, "case").WithArguments("pattern matching", "7.0").WithLocation(10, 13)); CreateCompilation(text, parseOptions: TestOptions.Regular7_3).VerifyDiagnostics(); CreateCompilation(text, parseOptions: TestOptions.Regular8).VerifyDiagnostics(); } #endregion #region regressions [WorkItem(543849, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543849")] [Fact] public void NamespaceInCaseExpression() { var text = @"class Test { static void Main() { int x = 5; switch (x) { case System: break; case 5: goto System; } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (8,18): error CS0118: 'System' is a namespace but is used like a variable // case System: Diagnostic(ErrorCode.ERR_BadSKknown, "System").WithArguments("System", "namespace", "variable").WithLocation(8, 18), // (11,22): error CS0159: No such label 'System' within the scope of the goto statement // goto System; Diagnostic(ErrorCode.ERR_LabelNotFound, "System").WithArguments("System").WithLocation(11, 22), // (10,13): error CS8070: Control cannot fall out of switch from final case label ('case 5:') // case 5: Diagnostic(ErrorCode.ERR_SwitchFallOut, "case 5:").WithArguments("case 5:").WithLocation(10, 13) ); CreateCompilation(text).VerifyDiagnostics( // (8,18): error CS0118: 'System' is a namespace but is used like a variable // case System: Diagnostic(ErrorCode.ERR_BadSKknown, "System").WithArguments("System", "namespace", "variable").WithLocation(8, 18), // (11,22): error CS0159: No such label 'System' within the scope of the goto statement // goto System; Diagnostic(ErrorCode.ERR_LabelNotFound, "System").WithArguments("System").WithLocation(11, 22), // (10,13): error CS8070: Control cannot fall out of switch from final case label ('case 5:') // case 5: Diagnostic(ErrorCode.ERR_SwitchFallOut, "case 5:").WithArguments("case 5:").WithLocation(10, 13) ); } [Fact] public void SwitchOnBoolBeforeCSharp2() { var source = @" class C { void M(bool b) { switch(b) { default: break; } } } "; CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp2)).VerifyDiagnostics(); CreateCompilation(source, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp1)).VerifyDiagnostics( // (6,16): error CS8022: Feature 'switch on boolean type' is not available in C# 1. Please use language version 2 or greater. // switch(b) Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion1, "b").WithArguments("switch on boolean type", "2")); } [Fact] public void SmallUnsignedEdgeCase01() { var source = @" using System; class C { static void Main(string[] args) { RunTest(126); RunTest(127); RunTest(128); RunTest(129); void RunTest(byte testByte) { switch (testByte) { case 127: // 0111 1111 case 128: // 1000 0000 Console.Write(0); break; default: Console.Write(1); break; } } } }"; var comp = CompileAndVerify(source, expectedOutput: @"1001"); comp.VerifyDiagnostics(); } [Fact] public void SmallUnsignedEdgeCase02() { var source = @" using System; class C { static void Main(string[] args) { RunTest(32766); RunTest(32767); RunTest(32768); RunTest(32769); void RunTest(ushort testUshort) { switch (testUshort) { case 32767: // 0111 1111 1111 1111 case 32768: // 1000 0000 0000 0000 Console.Write(0); break; default: Console.Write(1); break; } } } }"; var comp = CompileAndVerify(source, expectedOutput: @"1001"); comp.VerifyDiagnostics(); } [Fact] public void ConstantNullSwitchExpression() { var text = @" public class TestClass { public static void Main() { const string s = null; switch (s) { default: break; //1 case null: break; //2 } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics( // (10,17): warning CS0162: Unreachable code detected // break; //1 Diagnostic(ErrorCode.WRN_UnreachableCode, "break").WithLocation(10, 17) ); CreateCompilation(text).VerifyDiagnostics( // (10,17): warning CS0162: Unreachable code detected // break; //1 Diagnostic(ErrorCode.WRN_UnreachableCode, "break").WithLocation(10, 17) ); } [Fact] [WorkItem(33783, "https://github.com/dotnet/roslyn/issues/33783")] public void UnreachableDefaultInBoolSwitch() { var text = @" public class TestClass { public static void Main() { bool b = false; switch (b) { case true: break; case false: break; default: break; //1 } } }"; CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics(); CreateCompilation(text, parseOptions: TestOptions.Regular7_3).VerifyDiagnostics(); CreateCompilation(text).VerifyDiagnostics( // (14,17): warning CS0162: Unreachable code detected // break; //1 Diagnostic(ErrorCode.WRN_UnreachableCode, "break").WithLocation(14, 17)); } [Fact, WorkItem(47878, "https://github.com/dotnet/roslyn/issues/47878")] public void Bug47878() { var text = @" using System; public class C { public static void Main() { int x1 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) switch { (1, 2, 3, 4, 5, 6, 7, 8, 9, 10) => 1, _ => -1, }; int x2 = (1, 2, 3, 4, 5, 6, 7, 8) switch { (1, 2, 3, 4, 5, 6, 7, 8) => 1, _ => -1, }; int x3 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) switch { (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16) => 1, _ => -1, }; int x4 = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) switch { (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) => 1, _ => -1, }; Console.WriteLine($""{x1} {x2} {x3} {x4}""); } } "; var comp = CompileAndVerify(text, expectedOutput: "1 1 1 1"); comp.VerifyDiagnostics(); } [Fact, WorkItem(47878, "https://github.com/dotnet/roslyn/issues/47878")] public void VerifyIL_8ElementsTuple() { var text = @" using System; public class C { public static void Main() { int x = (1, 2, 3, 4, 5, 6, 7, 8) switch { (1, 2, 3, 4, 5, 6, 7, 8) => 1, _ => -1, }; Console.WriteLine(x); } } "; CompileAndVerify(text, expectedOutput: "1").VerifyIL("C.Main", @" { // Code size 110 (0x6e) .maxstack 9 .locals init (int V_0, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>> V_1) IL_0000: ldloca.s V_1 IL_0002: ldc.i4.1 IL_0003: ldc.i4.2 IL_0004: ldc.i4.3 IL_0005: ldc.i4.4 IL_0006: ldc.i4.5 IL_0007: ldc.i4.6 IL_0008: ldc.i4.7 IL_0009: ldc.i4.8 IL_000a: newobj ""System.ValueTuple<int>..ctor(int)"" IL_000f: call ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>..ctor(int, int, int, int, int, int, int, System.ValueTuple<int>)"" IL_0014: ldloc.1 IL_0015: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item1"" IL_001a: ldc.i4.1 IL_001b: bne.un.s IL_0065 IL_001d: ldloc.1 IL_001e: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item2"" IL_0023: ldc.i4.2 IL_0024: bne.un.s IL_0065 IL_0026: ldloc.1 IL_0027: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item3"" IL_002c: ldc.i4.3 IL_002d: bne.un.s IL_0065 IL_002f: ldloc.1 IL_0030: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item4"" IL_0035: ldc.i4.4 IL_0036: bne.un.s IL_0065 IL_0038: ldloc.1 IL_0039: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item5"" IL_003e: ldc.i4.5 IL_003f: bne.un.s IL_0065 IL_0041: ldloc.1 IL_0042: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item6"" IL_0047: ldc.i4.6 IL_0048: bne.un.s IL_0065 IL_004a: ldloc.1 IL_004b: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item7"" IL_0050: ldc.i4.7 IL_0051: bne.un.s IL_0065 IL_0053: ldloc.1 IL_0054: ldfld ""System.ValueTuple<int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Rest"" IL_0059: ldfld ""int System.ValueTuple<int>.Item1"" IL_005e: ldc.i4.8 IL_005f: bne.un.s IL_0065 IL_0061: ldc.i4.1 IL_0062: stloc.0 IL_0063: br.s IL_0067 IL_0065: ldc.i4.m1 IL_0066: stloc.0 IL_0067: ldloc.0 IL_0068: call ""void System.Console.WriteLine(int)"" IL_006d: ret } "); } [Fact, WorkItem(47878, "https://github.com/dotnet/roslyn/issues/47878")] public void VerifyIL_GreaterThan8ElementsTuple_01() { var text = @" using System; public class C { public static void Main() { int x = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) switch { (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) => 1, _ => -1, }; Console.WriteLine(x); } } "; CompileAndVerify(text, expectedOutput: "1").VerifyIL("C.Main", @" { // Code size 204 (0xcc) .maxstack 14 .locals init (int V_0, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> V_1) IL_0000: ldloca.s V_1 IL_0002: ldc.i4.1 IL_0003: ldc.i4.2 IL_0004: ldc.i4.3 IL_0005: ldc.i4.4 IL_0006: ldc.i4.5 IL_0007: ldc.i4.6 IL_0008: ldc.i4.7 IL_0009: ldc.i4.8 IL_000a: ldc.i4.s 9 IL_000c: ldc.i4.s 10 IL_000e: ldc.i4.s 11 IL_0010: ldc.i4.s 12 IL_0012: ldc.i4.s 13 IL_0014: newobj ""System.ValueTuple<int, int, int, int, int, int>..ctor(int, int, int, int, int, int)"" IL_0019: call ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>..ctor(int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>)"" IL_001e: ldloc.1 IL_001f: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item1"" IL_0024: ldc.i4.1 IL_0025: bne.un IL_00c3 IL_002a: ldloc.1 IL_002b: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item2"" IL_0030: ldc.i4.2 IL_0031: bne.un IL_00c3 IL_0036: ldloc.1 IL_0037: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item3"" IL_003c: ldc.i4.3 IL_003d: bne.un IL_00c3 IL_0042: ldloc.1 IL_0043: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item4"" IL_0048: ldc.i4.4 IL_0049: bne.un.s IL_00c3 IL_004b: ldloc.1 IL_004c: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item5"" IL_0051: ldc.i4.5 IL_0052: bne.un.s IL_00c3 IL_0054: ldloc.1 IL_0055: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item6"" IL_005a: ldc.i4.6 IL_005b: bne.un.s IL_00c3 IL_005d: ldloc.1 IL_005e: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item7"" IL_0063: ldc.i4.7 IL_0064: bne.un.s IL_00c3 IL_0066: ldloc.1 IL_0067: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_006c: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item1"" IL_0071: ldc.i4.8 IL_0072: bne.un.s IL_00c3 IL_0074: ldloc.1 IL_0075: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_007a: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item2"" IL_007f: ldc.i4.s 9 IL_0081: bne.un.s IL_00c3 IL_0083: ldloc.1 IL_0084: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_0089: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item3"" IL_008e: ldc.i4.s 10 IL_0090: bne.un.s IL_00c3 IL_0092: ldloc.1 IL_0093: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_0098: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item4"" IL_009d: ldc.i4.s 11 IL_009f: bne.un.s IL_00c3 IL_00a1: ldloc.1 IL_00a2: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_00a7: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item5"" IL_00ac: ldc.i4.s 12 IL_00ae: bne.un.s IL_00c3 IL_00b0: ldloc.1 IL_00b1: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_00b6: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item6"" IL_00bb: ldc.i4.s 13 IL_00bd: bne.un.s IL_00c3 IL_00bf: ldc.i4.1 IL_00c0: stloc.0 IL_00c1: br.s IL_00c5 IL_00c3: ldc.i4.m1 IL_00c4: stloc.0 IL_00c5: ldloc.0 IL_00c6: call ""void System.Console.WriteLine(int)"" IL_00cb: ret } "); } [Fact, WorkItem(47878, "https://github.com/dotnet/roslyn/issues/47878")] public void VerifyIL_GreaterThan8ElementsTuple_02() { var text = @" using System; public class C { public static void Main() { int x = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13) switch { (1, 2, 3, 4, 5, 6, not 7, 8, 9, 10, 11, 12, 13) => 1, _ => -1, }; Console.WriteLine(x); } } "; CompileAndVerify(text, expectedOutput: "-1").VerifyIL("C.Main", @" { // Code size 204 (0xcc) .maxstack 14 .locals init (int V_0, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> V_1) IL_0000: ldloca.s V_1 IL_0002: ldc.i4.1 IL_0003: ldc.i4.2 IL_0004: ldc.i4.3 IL_0005: ldc.i4.4 IL_0006: ldc.i4.5 IL_0007: ldc.i4.6 IL_0008: ldc.i4.7 IL_0009: ldc.i4.8 IL_000a: ldc.i4.s 9 IL_000c: ldc.i4.s 10 IL_000e: ldc.i4.s 11 IL_0010: ldc.i4.s 12 IL_0012: ldc.i4.s 13 IL_0014: newobj ""System.ValueTuple<int, int, int, int, int, int>..ctor(int, int, int, int, int, int)"" IL_0019: call ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>..ctor(int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>)"" IL_001e: ldloc.1 IL_001f: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item1"" IL_0024: ldc.i4.1 IL_0025: bne.un IL_00c3 IL_002a: ldloc.1 IL_002b: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item2"" IL_0030: ldc.i4.2 IL_0031: bne.un IL_00c3 IL_0036: ldloc.1 IL_0037: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item3"" IL_003c: ldc.i4.3 IL_003d: bne.un IL_00c3 IL_0042: ldloc.1 IL_0043: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item4"" IL_0048: ldc.i4.4 IL_0049: bne.un.s IL_00c3 IL_004b: ldloc.1 IL_004c: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item5"" IL_0051: ldc.i4.5 IL_0052: bne.un.s IL_00c3 IL_0054: ldloc.1 IL_0055: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item6"" IL_005a: ldc.i4.6 IL_005b: bne.un.s IL_00c3 IL_005d: ldloc.1 IL_005e: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item7"" IL_0063: ldc.i4.7 IL_0064: beq.s IL_00c3 IL_0066: ldloc.1 IL_0067: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_006c: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item1"" IL_0071: ldc.i4.8 IL_0072: bne.un.s IL_00c3 IL_0074: ldloc.1 IL_0075: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_007a: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item2"" IL_007f: ldc.i4.s 9 IL_0081: bne.un.s IL_00c3 IL_0083: ldloc.1 IL_0084: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_0089: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item3"" IL_008e: ldc.i4.s 10 IL_0090: bne.un.s IL_00c3 IL_0092: ldloc.1 IL_0093: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_0098: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item4"" IL_009d: ldc.i4.s 11 IL_009f: bne.un.s IL_00c3 IL_00a1: ldloc.1 IL_00a2: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_00a7: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item5"" IL_00ac: ldc.i4.s 12 IL_00ae: bne.un.s IL_00c3 IL_00b0: ldloc.1 IL_00b1: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_00b6: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item6"" IL_00bb: ldc.i4.s 13 IL_00bd: bne.un.s IL_00c3 IL_00bf: ldc.i4.1 IL_00c0: stloc.0 IL_00c1: br.s IL_00c5 IL_00c3: ldc.i4.m1 IL_00c4: stloc.0 IL_00c5: ldloc.0 IL_00c6: call ""void System.Console.WriteLine(int)"" IL_00cb: ret } "); } [Fact, WorkItem(47878, "https://github.com/dotnet/roslyn/issues/47878")] public void VerifyIL_GreaterThan8ElementsTuple_03() { var text = @" using System; public class C { public static void Main() { int x = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) switch { (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) => 1, _ => -1, }; Console.WriteLine(x); } } "; CompileAndVerify(text).VerifyIL("C.Main", @" { // Code size 388 (0x184) .maxstack 21 .locals init (int V_0, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>> V_1) IL_0000: ldloca.s V_1 IL_0002: ldc.i4.1 IL_0003: ldc.i4.2 IL_0004: ldc.i4.3 IL_0005: ldc.i4.4 IL_0006: ldc.i4.5 IL_0007: ldc.i4.6 IL_0008: ldc.i4.7 IL_0009: ldc.i4.8 IL_000a: ldc.i4.s 9 IL_000c: ldc.i4.s 10 IL_000e: ldc.i4.s 11 IL_0010: ldc.i4.s 12 IL_0012: ldc.i4.s 13 IL_0014: ldc.i4.s 14 IL_0016: ldc.i4.s 15 IL_0018: ldc.i4.s 16 IL_001a: ldc.i4.s 17 IL_001c: ldc.i4.s 18 IL_001e: ldc.i4.s 19 IL_0020: ldc.i4.s 20 IL_0022: newobj ""System.ValueTuple<int, int, int, int, int, int>..ctor(int, int, int, int, int, int)"" IL_0027: newobj ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>..ctor(int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>)"" IL_002c: call ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>..ctor(int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>)"" IL_0031: ldloc.1 IL_0032: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Item1"" IL_0037: ldc.i4.1 IL_0038: bne.un IL_017b IL_003d: ldloc.1 IL_003e: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Item2"" IL_0043: ldc.i4.2 IL_0044: bne.un IL_017b IL_0049: ldloc.1 IL_004a: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Item3"" IL_004f: ldc.i4.3 IL_0050: bne.un IL_017b IL_0055: ldloc.1 IL_0056: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Item4"" IL_005b: ldc.i4.4 IL_005c: bne.un IL_017b IL_0061: ldloc.1 IL_0062: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Item5"" IL_0067: ldc.i4.5 IL_0068: bne.un IL_017b IL_006d: ldloc.1 IL_006e: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Item6"" IL_0073: ldc.i4.6 IL_0074: bne.un IL_017b IL_0079: ldloc.1 IL_007a: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Item7"" IL_007f: ldc.i4.7 IL_0080: bne.un IL_017b IL_0085: ldloc.1 IL_0086: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_008b: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item1"" IL_0090: ldc.i4.8 IL_0091: bne.un IL_017b IL_0096: ldloc.1 IL_0097: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_009c: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item2"" IL_00a1: ldc.i4.s 9 IL_00a3: bne.un IL_017b IL_00a8: ldloc.1 IL_00a9: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_00ae: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item3"" IL_00b3: ldc.i4.s 10 IL_00b5: bne.un IL_017b IL_00ba: ldloc.1 IL_00bb: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_00c0: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item4"" IL_00c5: ldc.i4.s 11 IL_00c7: bne.un IL_017b IL_00cc: ldloc.1 IL_00cd: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_00d2: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item5"" IL_00d7: ldc.i4.s 12 IL_00d9: bne.un IL_017b IL_00de: ldloc.1 IL_00df: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_00e4: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item6"" IL_00e9: ldc.i4.s 13 IL_00eb: bne.un IL_017b IL_00f0: ldloc.1 IL_00f1: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_00f6: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Item7"" IL_00fb: ldc.i4.s 14 IL_00fd: bne.un.s IL_017b IL_00ff: ldloc.1 IL_0100: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_0105: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_010a: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item1"" IL_010f: ldc.i4.s 15 IL_0111: bne.un.s IL_017b IL_0113: ldloc.1 IL_0114: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_0119: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_011e: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item2"" IL_0123: ldc.i4.s 16 IL_0125: bne.un.s IL_017b IL_0127: ldloc.1 IL_0128: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_012d: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_0132: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item3"" IL_0137: ldc.i4.s 17 IL_0139: bne.un.s IL_017b IL_013b: ldloc.1 IL_013c: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_0141: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_0146: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item4"" IL_014b: ldc.i4.s 18 IL_014d: bne.un.s IL_017b IL_014f: ldloc.1 IL_0150: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_0155: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_015a: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item5"" IL_015f: ldc.i4.s 19 IL_0161: bne.un.s IL_017b IL_0163: ldloc.1 IL_0164: ldfld ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>>.Rest"" IL_0169: ldfld ""System.ValueTuple<int, int, int, int, int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int, int, int, int, int>>.Rest"" IL_016e: ldfld ""int System.ValueTuple<int, int, int, int, int, int>.Item6"" IL_0173: ldc.i4.s 20 IL_0175: bne.un.s IL_017b IL_0177: ldc.i4.1 IL_0178: stloc.0 IL_0179: br.s IL_017d IL_017b: ldc.i4.m1 IL_017c: stloc.0 IL_017d: ldloc.0 IL_017e: call ""void System.Console.WriteLine(int)"" IL_0183: ret } "); } [Fact, WorkItem(47878, "https://github.com/dotnet/roslyn/issues/47878")] public void VerifyIL_8ElementsTuple_SideEffects_DefaultLabel() { var text = @" using System; using System.Runtime.CompilerServices; public class C { public static void Main() { try { int x = (M(1), M(2), M(3), M(4), M(5), M(6), M(7), M(8)) switch { (1, 2, 3, 4, 5, 6, 7, 7) => 1, }; Console.WriteLine(x); } catch (SwitchExpressionException ex) { Console.Write(""💥""); } } static int M(int x) { Console.Write(x); return x; } } namespace System.Runtime.CompilerServices { public class SwitchExpressionException : InvalidOperationException { public SwitchExpressionException() {} public SwitchExpressionException(object unmatchedValue) => UnmatchedValue = unmatchedValue; public object UnmatchedValue { get; } } } "; CompileAndVerify(text, expectedOutput: "12345678💥").VerifyIL("C.Main", @" { // Code size 173 (0xad) .maxstack 8 .locals init (int V_0, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>> V_1) .try { IL_0000: ldc.i4.1 IL_0001: call ""int C.M(int)"" IL_0006: ldc.i4.2 IL_0007: call ""int C.M(int)"" IL_000c: ldc.i4.3 IL_000d: call ""int C.M(int)"" IL_0012: ldc.i4.4 IL_0013: call ""int C.M(int)"" IL_0018: ldc.i4.5 IL_0019: call ""int C.M(int)"" IL_001e: ldc.i4.6 IL_001f: call ""int C.M(int)"" IL_0024: ldc.i4.7 IL_0025: call ""int C.M(int)"" IL_002a: ldc.i4.8 IL_002b: call ""int C.M(int)"" IL_0030: newobj ""System.ValueTuple<int>..ctor(int)"" IL_0035: newobj ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>..ctor(int, int, int, int, int, int, int, System.ValueTuple<int>)"" IL_003a: stloc.1 IL_003b: ldloc.1 IL_003c: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item1"" IL_0041: ldc.i4.1 IL_0042: bne.un.s IL_008c IL_0044: ldloc.1 IL_0045: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item2"" IL_004a: ldc.i4.2 IL_004b: bne.un.s IL_008c IL_004d: ldloc.1 IL_004e: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item3"" IL_0053: ldc.i4.3 IL_0054: bne.un.s IL_008c IL_0056: ldloc.1 IL_0057: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item4"" IL_005c: ldc.i4.4 IL_005d: bne.un.s IL_008c IL_005f: ldloc.1 IL_0060: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item5"" IL_0065: ldc.i4.5 IL_0066: bne.un.s IL_008c IL_0068: ldloc.1 IL_0069: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item6"" IL_006e: ldc.i4.6 IL_006f: bne.un.s IL_008c IL_0071: ldloc.1 IL_0072: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Item7"" IL_0077: ldc.i4.7 IL_0078: bne.un.s IL_008c IL_007a: ldloc.1 IL_007b: ldfld ""System.ValueTuple<int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>.Rest"" IL_0080: ldfld ""int System.ValueTuple<int>.Item1"" IL_0085: ldc.i4.7 IL_0086: bne.un.s IL_008c IL_0088: ldc.i4.1 IL_0089: stloc.0 IL_008a: br.s IL_0097 IL_008c: ldloc.1 IL_008d: box ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int>>"" IL_0092: call ""void <PrivateImplementationDetails>.ThrowSwitchExpressionException(object)"" IL_0097: ldloc.0 IL_0098: call ""void System.Console.WriteLine(int)"" IL_009d: leave.s IL_00ac } catch System.Runtime.CompilerServices.SwitchExpressionException { IL_009f: pop IL_00a0: ldstr ""💥"" IL_00a5: call ""void System.Console.Write(string)"" IL_00aa: leave.s IL_00ac } IL_00ac: ret } "); } [Fact, WorkItem(47878, "https://github.com/dotnet/roslyn/issues/47878")] public void VerifyIL_9ElementsTuple_SideEffects_DefaultLabel() { var text = @" using System; using System.Runtime.CompilerServices; public class C { public static void Main() { try { int x = (M(1), M(2), M(3), M(4), M(5), M(6), M(7), M(8), M(9)) switch { (1, 2, 3, 4, 5, 6, 7, 8, 8) => 1, }; Console.WriteLine(x); } catch (SwitchExpressionException ex) { Console.Write(""💥""); } } static int M(int x) { Console.Write(x); return x; } } namespace System.Runtime.CompilerServices { public class SwitchExpressionException : InvalidOperationException { public SwitchExpressionException() {} public SwitchExpressionException(object unmatchedValue) => UnmatchedValue = unmatchedValue; public object UnmatchedValue { get; } } } "; CompileAndVerify(text, expectedOutput: "123456789💥").VerifyIL("C.Main", @" { // Code size 194 (0xc2) .maxstack 9 .locals init (int V_0, System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int>> V_1) .try { IL_0000: ldc.i4.1 IL_0001: call ""int C.M(int)"" IL_0006: ldc.i4.2 IL_0007: call ""int C.M(int)"" IL_000c: ldc.i4.3 IL_000d: call ""int C.M(int)"" IL_0012: ldc.i4.4 IL_0013: call ""int C.M(int)"" IL_0018: ldc.i4.5 IL_0019: call ""int C.M(int)"" IL_001e: ldc.i4.6 IL_001f: call ""int C.M(int)"" IL_0024: ldc.i4.7 IL_0025: call ""int C.M(int)"" IL_002a: ldc.i4.8 IL_002b: call ""int C.M(int)"" IL_0030: ldc.i4.s 9 IL_0032: call ""int C.M(int)"" IL_0037: newobj ""System.ValueTuple<int, int>..ctor(int, int)"" IL_003c: newobj ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int>>..ctor(int, int, int, int, int, int, int, System.ValueTuple<int, int>)"" IL_0041: stloc.1 IL_0042: ldloc.1 IL_0043: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int>>.Item1"" IL_0048: ldc.i4.1 IL_0049: bne.un.s IL_00a1 IL_004b: ldloc.1 IL_004c: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int>>.Item2"" IL_0051: ldc.i4.2 IL_0052: bne.un.s IL_00a1 IL_0054: ldloc.1 IL_0055: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int>>.Item3"" IL_005a: ldc.i4.3 IL_005b: bne.un.s IL_00a1 IL_005d: ldloc.1 IL_005e: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int>>.Item4"" IL_0063: ldc.i4.4 IL_0064: bne.un.s IL_00a1 IL_0066: ldloc.1 IL_0067: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int>>.Item5"" IL_006c: ldc.i4.5 IL_006d: bne.un.s IL_00a1 IL_006f: ldloc.1 IL_0070: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int>>.Item6"" IL_0075: ldc.i4.6 IL_0076: bne.un.s IL_00a1 IL_0078: ldloc.1 IL_0079: ldfld ""int System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int>>.Item7"" IL_007e: ldc.i4.7 IL_007f: bne.un.s IL_00a1 IL_0081: ldloc.1 IL_0082: ldfld ""System.ValueTuple<int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int>>.Rest"" IL_0087: ldfld ""int System.ValueTuple<int, int>.Item1"" IL_008c: ldc.i4.8 IL_008d: bne.un.s IL_00a1 IL_008f: ldloc.1 IL_0090: ldfld ""System.ValueTuple<int, int> System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int>>.Rest"" IL_0095: ldfld ""int System.ValueTuple<int, int>.Item2"" IL_009a: ldc.i4.8 IL_009b: bne.un.s IL_00a1 IL_009d: ldc.i4.1 IL_009e: stloc.0 IL_009f: br.s IL_00ac IL_00a1: ldloc.1 IL_00a2: box ""System.ValueTuple<int, int, int, int, int, int, int, System.ValueTuple<int, int>>"" IL_00a7: call ""void <PrivateImplementationDetails>.ThrowSwitchExpressionException(object)"" IL_00ac: ldloc.0 IL_00ad: call ""void System.Console.WriteLine(int)"" IL_00b2: leave.s IL_00c1 } catch System.Runtime.CompilerServices.SwitchExpressionException { IL_00b4: pop IL_00b5: ldstr ""💥"" IL_00ba: call ""void System.Console.Write(string)"" IL_00bf: leave.s IL_00c1 } IL_00c1: ret } "); } #endregion } }