/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/CSharp/Test/Emit/BreakingChanges.cs
1 728 строк
57 KB
AlekseyTs
Avoid stack overflow due to deep recursion on long chain of calls. (#67913)
29 апр 2023, 19:19
Не верифицирован
29 апр 2023, 19:19
53ac77e
Код
Авторство
О чём код?
// 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.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { public class BreakingChanges : CSharpTestBase { [Fact, WorkItem(527050, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527050")] [Trait("Feature", "Directives")] public void TestCS1024DefineWithUnicodeInMiddle() { var test = @"#de\u0066in\U00000065 ABC"; // This is now a negative test, this should not be allowed. SyntaxFactory.ParseSyntaxTree(test).GetDiagnostics().Verify(Diagnostic(ErrorCode.ERR_PPDirectiveExpected, @"de\u0066in\U00000065")); } [Fact, WorkItem(527951, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527951")] public void CS0133ERR_NotConstantExpression05() { var text = @" class A { public void Do() { const object o1 = null; const string o2 = (string)o1; // Dev10 reports CS0133 } } "; var comp = CreateCompilation(text); comp.VerifyDiagnostics( // (7,22): warning CS0219: The variable 'o2' is assigned but its value is never used // const string o2 = (string)o1; // Dev10 reports CS0133 Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "o2").WithArguments("o2") ); } [WorkItem(527943, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527943")] [Fact] public void CS0146ERR_CircularBase05() { var text = @" interface IFace<T> { } class B : IFace<B.C.D> { public class C { public class D { } } } "; var comp = CreateCompilation(text); // In Dev10, there was an error - ErrorCode.ERR_CircularBase at (4,7) Assert.Equal(0, comp.GetDiagnostics().Count()); } [WorkItem(540371, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540371"), WorkItem(530792, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530792")] [Fact] public void CS0507ERR_CantChangeAccessOnOverride_TestSynthesizedSealedAccessorsInDifferentAssembly() { var source1 = @" using System.Collections.Generic; public class Base<T> { public virtual List<T> Property1 { get { return null; } protected internal set { } } public virtual List<T> Property2 { protected internal get { return null; } set { } } }"; var compilation1 = CreateCompilation(source1); var source2 = @" using System.Collections.Generic; public class Derived : Base<int> { public sealed override List<int> Property1 { get { return null; } } public sealed override List<int> Property2 { set { } } }"; var comp = CreateCompilation(source2, new[] { new CSharpCompilationReference(compilation1) }); comp.VerifyDiagnostics(); // This is not a breaking change - but it is a change in behavior from Dev10 // Dev10 used to report following errors - // Error CS0507: 'Derived.Property1.set': cannot change access modifiers when overriding 'protected' inherited member 'Base<int>.Property1.set' // Error CS0507: 'Derived.Property2.get': cannot change access modifiers when overriding 'protected' inherited member 'Base<int>.Property2.get' // Roslyn makes this case work by synthesizing 'protected' accessors for the missing ones var baseClass = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("Base"); var baseProperty1 = baseClass.GetMember<PropertySymbol>("Property1"); var baseProperty2 = baseClass.GetMember<PropertySymbol>("Property2"); Assert.Equal(Accessibility.Public, baseProperty1.DeclaredAccessibility); Assert.Equal(Accessibility.Public, baseProperty1.GetMethod.DeclaredAccessibility); Assert.Equal(Accessibility.ProtectedOrInternal, baseProperty1.SetMethod.DeclaredAccessibility); Assert.Equal(Accessibility.Public, baseProperty2.DeclaredAccessibility); Assert.Equal(Accessibility.ProtectedOrInternal, baseProperty2.GetMethod.DeclaredAccessibility); Assert.Equal(Accessibility.Public, baseProperty2.SetMethod.DeclaredAccessibility); var derivedClass = comp.GlobalNamespace.GetMember<NamedTypeSymbol>("Derived"); var derivedProperty1 = derivedClass.GetMember<SourcePropertySymbol>("Property1"); var derivedProperty2 = derivedClass.GetMember<SourcePropertySymbol>("Property2"); Assert.Equal(Accessibility.Public, derivedProperty1.DeclaredAccessibility); Assert.Equal(Accessibility.Public, derivedProperty1.GetMethod.DeclaredAccessibility); Assert.Null(derivedProperty1.SetMethod); Assert.Equal(Accessibility.Public, derivedProperty2.DeclaredAccessibility); Assert.Null(derivedProperty2.GetMethod); Assert.Equal(Accessibility.Public, derivedProperty2.SetMethod.DeclaredAccessibility); var derivedProperty1Synthesized = derivedProperty1.SynthesizedSealedAccessorOpt; var derivedProperty2Synthesized = derivedProperty2.SynthesizedSealedAccessorOpt; Assert.Equal(MethodKind.PropertySet, derivedProperty1Synthesized.MethodKind); Assert.Equal(Accessibility.Protected, derivedProperty1Synthesized.DeclaredAccessibility); Assert.Equal(MethodKind.PropertyGet, derivedProperty2Synthesized.MethodKind); Assert.Equal(Accessibility.Protected, derivedProperty2Synthesized.DeclaredAccessibility); } // Confirm that this error no longer exists [Fact] public void CS0609ERR_NameAttributeOnOverride() { var text = @" using System.Runtime.CompilerServices; public class @idx { public virtual int this[int iPropIndex] { get { return 0; } set { } } } public class MonthDays : idx { [IndexerName(""MonthInfoIndexer"")] public override int this[int iPropIndex] { get { return 1; } set { } } } "; var compilation = CreateCompilation(text); compilation.VerifyDiagnostics(); var indexer = compilation.GlobalNamespace.GetMember<NamedTypeSymbol>("MonthDays").Indexers.Single(); Assert.Equal(Microsoft.CodeAnalysis.WellKnownMemberNames.Indexer, indexer.Name); Assert.Equal("MonthInfoIndexer", indexer.MetadataName); } [WorkItem(527116, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527116")] [Fact] public void RegressWarningInSingleMultiLineMixedXml() { var text = @" /// <summary> /** This is the summary */ /// </summary> class Test { /** <summary> */ /// This is the summary1 /** </summary> */ public int Field = 0; /** <summary> */ /// This is the summary2 /// </summary> string Prop { get; set; } /// <summary> /** This is the summary3 * </summary> */ static int Main() { return new Test().Field; } } "; var tree = Parse(text, options: TestOptions.RegularWithDocumentationComments); Assert.NotNull(tree); Assert.Equal(text, tree.GetCompilationUnitRoot().ToFullString()); // Dev10 allows (no warning) // Roslyn gives Warning CS1570 - "XML Comment has badly formed XML..." Assert.Equal(8, tree.GetDiagnostics().Count()); } [Fact, WorkItem(527093, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/527093")] public void NoCS1570ForUndefinedXmlNamespace() { var text = @" /// <xml> xmlns:s=""uuid: BDC6E3F0-6DA3-11d1-A2A3 - 00AA00C14882""> /// <s:inventory> /// </s:inventory> /// </xml> class A { } "; var tree = Parse(text, options: TestOptions.RegularWithDocumentationComments); Assert.NotNull(tree); Assert.Equal(text, tree.GetCompilationUnitRoot().ToFullString()); // Native Warning CS1570 - "XML Comment has badly formed XML..." // Roslyn no Assert.Empty(tree.GetDiagnostics()); } [Fact, WorkItem(541345, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541345")] public void CS0019_TestNullCoalesceWithNullOperandsErrors() { var source = @" class Program { static void Main() { // This is acceptable by the native compiler and treated as a non-constant null literal. // That violates the specification; we now correctly treat this as an error. object a = null ?? null; // The null coalescing operator never produces a compile-time constant even when // the arguments are constants. const object b = null ?? ""ABC""; const string c = ""DEF"" ?? null; const int d = (int?)null ?? 123; // It is legal, though pointless, to use null literals and constants in coalescing // expressions, provided you don't try to make the result a constant. These should // produce no errors: object z = null ?? ""GHI""; string y = ""JKL"" ?? null; int x = (int?)null ?? 456; } } "; CreateCompilation(source).VerifyDiagnostics( Diagnostic(ErrorCode.ERR_BadBinaryOps, "null ?? null").WithArguments("??", "<null>", "<null>"), Diagnostic(ErrorCode.ERR_NotConstantExpression, @"null ?? ""ABC""").WithArguments("b"), Diagnostic(ErrorCode.ERR_NotConstantExpression, @"""DEF"" ?? null").WithArguments("c"), Diagnostic(ErrorCode.ERR_NotConstantExpression, "(int?)null ?? 123").WithArguments("d")); } [Fact, WorkItem(528676, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528676"), WorkItem(528676, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528676")] public // CS0657WRN_AttributeLocationOnBadDeclaration_AfterAttrDeclOrDelegate void CS1730ERR_CantUseAttributeOnInvaildLocation() { var test = @"using System; [AttributeUsage(AttributeTargets.All)] public class Goo : Attribute { public int Name; public Goo(int sName) { Name = sName; } } public delegate void EventHandler(object sender, EventArgs e); [assembly: Goo(5)] public class Test { } "; // In Dev10, this is a warning CS0657 // Diagnostic(ErrorCode.WRN_AttributeLocationOnBadDeclaration, "assembly").WithArguments("assembly", "type") SyntaxFactory.ParseSyntaxTree(test).GetDiagnostics().Verify(Diagnostic(ErrorCode.ERR_GlobalAttributesNotFirst, "assembly")); } [WorkItem(528711, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528711")] [Fact] public void CS9259_StructLayoutCycle() { var text = @"struct S1<T> { S1<S1<T>>.S2 x; struct S2 { static T x; } }"; var comp = CreateCompilation(text); comp.VerifyDiagnostics( // (3,18): warning CS0169: The field 'S1<T>.x' is never used // S1<S1<T>>.S2 x; Diagnostic(ErrorCode.WRN_UnreferencedField, "x").WithArguments("S1<T>.x").WithLocation(3, 18), // (6,18): warning CS0169: The field 'S1<T>.S2.x' is never used // static T x; Diagnostic(ErrorCode.WRN_UnreferencedField, "x").WithArguments("S1<T>.S2.x").WithLocation(6, 18) ); } [WorkItem(528094, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528094")] [Fact] public void FormattingUnicodeNotPartOfId() { string source = @" // <Area> Lexical - Unicode Characters</Area> // <Title> // Compiler considers identifiers, which differ only in formatting-character, as different ones; // This is not actually correct behavior but for the time being this is what we expect //</Title> //<RelatedBugs>DDB:133151</RelatedBugs> // <Expects Status=Success></Expects> #define A using System; class Program { static int Main() { int x = 0; #if A == A\uFFFB x=1; #endif Console.Write(x); return x; } } "; // Dev10 print '0' CompileAndVerify(source, expectedOutput: "1"); } [WorkItem(529000, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529000")] [Fact] public void NoCS0121ForSwitchedParamNames_Dev10814222() { string source = @" using System; // Bug Dev10: 814222 resolved as Won't Fix class Test { static void Main() { Console.Write(Bar(x: 1, y: ""T0"")); // Dev10:CS0121 Test01.Main01(); } public static int Bar(int x, string y, params int[] z) { return 1; } public static int Bar(string y, int x) { return 0; } // Roslyn pick this one } class Test01 { public static int Bar<T>(int x, T y, params int[] z) { return 1; } public static int Bar<T>(string y, int x) { return 0; } // Roslyn pick this one public static int Goo<T>(int x, T y) { return 1; } public static int Goo<T>(string y, int x) { return 0; } // Roslyn pick this one public static int AbcDef<T>(int x, T y) { return 0; } // Roslyn pick this one public static int AbcDef<T>(string y, int x, params int[] z) { return 1; } public static void Main01() { Console.Write(Bar<string>(x: 1, y: ""T1"")); // Dev10:CS0121 Console.Write(Goo<string>(x: 1, y: ""T2"")); // Dev10:CS0121 Console.Write(AbcDef<string>(x: 1, y: ""T3"")); // Dev10:CS0121 } } "; CompileAndVerify(source, expectedOutput: "0000"); } [WorkItem(529001, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529001")] [WorkItem(529002, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529002")] [WorkItem(1067, "https://github.com/dotnet/roslyn/issues/1067")] [Fact] public void CS0185ERR_LockNeedsReference_RequireRefType() { var source = @" class C { void M<T, TClass, TStruct>() where TClass : class where TStruct : struct { lock (default(object)) ; lock (default(int)) ; // CS0185 lock (default(T)) {} // new CS0185 - no constraints (Bug#10755) lock (default(TClass)) {} lock (default(TStruct)) {} // new CS0185 - constraints to value type (Bug#10756) lock (null) {} // new CS0185 - null is not an object type } } "; var standardCompilation = CreateCompilation(source); var strictCompilation = CreateCompilation(source, parseOptions: TestOptions.Regular.WithStrictFeature()); standardCompilation.VerifyDiagnostics( // (8,32): warning CS0642: Possible mistaken empty statement // lock (default(object)) ; Diagnostic(ErrorCode.WRN_PossibleMistakenNullStatement, ";").WithLocation(8, 32), // (9,29): warning CS0642: Possible mistaken empty statement // lock (default(int)) ; // CS0185 Diagnostic(ErrorCode.WRN_PossibleMistakenNullStatement, ";").WithLocation(9, 29), // (9,15): error CS0185: 'int' is not a reference type as required by the lock statement // lock (default(int)) ; // CS0185 Diagnostic(ErrorCode.ERR_LockNeedsReference, "default(int)").WithArguments("int").WithLocation(9, 15), // (12,15): error CS0185: 'TStruct' is not a reference type as required by the lock statement // lock (default(TStruct)) {} // new CS0185 - constraints to value type (Bug#10756) Diagnostic(ErrorCode.ERR_LockNeedsReference, "default(TStruct)").WithArguments("TStruct").WithLocation(12, 15) ); strictCompilation.VerifyDiagnostics( // (8,32): warning CS0642: Possible mistaken empty statement // lock (default(object)) ; Diagnostic(ErrorCode.WRN_PossibleMistakenNullStatement, ";").WithLocation(8, 32), // (9,29): warning CS0642: Possible mistaken empty statement // lock (default(int)) ; // CS0185 Diagnostic(ErrorCode.WRN_PossibleMistakenNullStatement, ";").WithLocation(9, 29), // (9,15): error CS0185: 'int' is not a reference type as required by the lock statement // lock (default(int)) ; // CS0185 Diagnostic(ErrorCode.ERR_LockNeedsReference, "default(int)").WithArguments("int").WithLocation(9, 15), // (10,15): error CS0185: 'T' is not a reference type as required by the lock statement // lock (default(T)) {} // new CS0185 - no constraints (Bug#10755) Diagnostic(ErrorCode.ERR_LockNeedsReference, "default(T)").WithArguments("T").WithLocation(10, 15), // (12,15): error CS0185: 'TStruct' is not a reference type as required by the lock statement // lock (default(TStruct)) {} // new CS0185 - constraints to value type (Bug#10756) Diagnostic(ErrorCode.ERR_LockNeedsReference, "default(TStruct)").WithArguments("TStruct").WithLocation(12, 15), // (13,15): error CS0185: '<null>' is not a reference type as required by the lock statement // lock (null) {} // new CS0185 - null is not an object type Diagnostic(ErrorCode.ERR_LockNeedsReference, "null").WithArguments("<null>").WithLocation(13, 15) ); } [WorkItem(528972, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528972")] [Fact] public void CS0121ERR_AmbigCall_Lambda1() { var text = @" using System; class A { static void Main() { Goo( delegate () { throw new Exception(); }); // both Dev10 & Roslyn no error Goo(x: () => { throw new Exception(); }); // Dev10: CS0121, Roslyn: no error } public static void Goo(Action x) { Console.WriteLine(1); } public static void Goo(Func<int> x) { Console.WriteLine(2); // Roslyn call this one } } "; // Dev11 FIXED this, no error anymore (So Not breaking Dev11) // Dev10 reports CS0121 because ExpressionBinder::WhichConversionIsBetter fails to unwrap // the NamedArgumentSpecification to find the UNBOUNDLAMBDA and, thus, never calls // WhichLambdaConversionIsBetter. CreateCompilation(text).VerifyDiagnostics(); } [Fact, WorkItem(529202, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529202")] public void NoCS0029_ErrorOnZeroToEnumToTypeConversion() { string source = @" class Program { static void Main() { S s = 0; } } enum E { Zero, One, Two } struct S { public static implicit operator S(E s) { return E.Zero; } }"; // Dev10/11: (11,9): error CS0029: Cannot implicitly convert type 'int' to 'S' CreateCompilation(source).VerifyDiagnostics( // (6,15): error CS0029: Cannot implicitly convert type 'int' to 'S' // S s = 0; Diagnostic(ErrorCode.ERR_NoImplicitConv, "0").WithArguments("int", "S") ); } [Fact, WorkItem(529242, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529242")] public void ThrowOverflowExceptionForUncheckedCheckedLambda() { string source = @" using System; class Program { static void Main() { Func<int, int> d = checked(delegate(int i) { int max = int.MaxValue; try { int n = max + 1; } catch (OverflowException) { Console.Write(""OV ""); // Roslyn throw } return i; }); var r = unchecked(d(9)); Console.Write(r); } } "; CompileAndVerify(source, expectedOutput: "OV 9"); } [WorkItem(529262, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529262")] [Fact] public void PartialMethod_ParameterAndTypeParameterNames() { var source = @"using System; using System.Reflection; partial class C { static partial void M<T, U>(T x, U y); static partial void M<T1, T2>(T1 y, T2 x) { Console.Write(""{0}, {1} | "", x, y); var m = typeof(C).GetMethod(""M"", BindingFlags.Static | BindingFlags.NonPublic); var tp = m.GetGenericArguments(); Console.Write(""{0}, {1} | "", tp[0].Name, tp[1].Name); var p = m.GetParameters(); Console.Write(""{0}, {1}"", p[0].Name, p[1].Name); } static void Main() { M(x: 1, y: 2); } }"; // Dev12 would emit "2, 1 | T1, T2 | x, y". CompileAndVerify(source, expectedOutput: "2, 1 | T, U | x, y"); } [Fact, WorkItem(529279, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529279")] public void NewCS0029_ImplicitlyUnwrapGenericNullable() { string source = @" public class GenC<T, U> where T : struct, U { public void Test(T t) { /*<bind>*/T? nt = t;/*</bind>*/ U valueUn = nt; } }"; var comp = CreateCompilation(source); comp.VerifyDiagnostics( // (7,21): error CS0029: Cannot implicitly convert type 'T?' to 'U' // U valueUn = nt; Diagnostic(ErrorCode.ERR_NoImplicitConv, "nt").WithArguments("T?", "U")); VerifyOperationTreeForTest<LocalDeclarationStatementSyntax>(comp, @" IVariableDeclarationGroupOperation (1 declarations) (OperationKind.VariableDeclarationGroup, Type: null) (Syntax: 'T? nt = t;') IVariableDeclarationOperation (1 declarators) (OperationKind.VariableDeclaration, Type: null) (Syntax: 'T? nt = t') Declarators: IVariableDeclaratorOperation (Symbol: T? nt) (OperationKind.VariableDeclarator, Type: null) (Syntax: 'nt = t') Initializer: IVariableInitializerOperation (OperationKind.VariableInitializer, Type: null) (Syntax: '= t') IConversionOperation (TryCast: False, Unchecked) (OperationKind.Conversion, Type: T?, IsImplicit) (Syntax: 't') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IParameterReferenceOperation: t (OperationKind.ParameterReference, Type: T) (Syntax: 't') Initializer: null "); } [Fact, WorkItem(529280, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529280"), WorkItem(546864, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546864")] public void ExplicitUDCWithGenericConstraints() { // This compiles successfully in Dev10 dues to a bug; a user-defined conversion // that converts from or to an interface should never be chosen. If you are // converting from Alpha to Beta via standard conversion, then Beta to Gamma // via user-defined conversion, then Gamma to Delta via standard conversion, then // none of Alpha, Beta, Gamma or Delta should be allowed to be interfaces. The // Dev10 compiler only checks Alpha and Delta, not Beta and Gamma. // // Unfortunately, real-world code both in devdiv and in the wild depends on this // behavior, so we are replicating the bug in Roslyn. string source = @"using System; public interface IGoo { void Method(); } public class CT : IGoo { public void Method() { } } public class GenC<T> where T : IGoo { public T valueT; public static explicit operator T(GenC<T> val) { Console.Write(""ExpConv""); return val.valueT; } } public class Test { public static void Main() { var _class = new GenC<IGoo>(); var ret = (CT)_class; } } "; // CompileAndVerify(source, expectedOutput: "ExpConv"); CreateCompilation(source).VerifyDiagnostics(); } [Fact, WorkItem(529362, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529362")] public void TestNullCoalescingOverImplicitExplicitUDC() { string source = @"using System; struct GenS<T> where T : struct { public static int Flag; public static explicit operator T?(GenS<T> s) { Flag = 3; return default(T); } public static implicit operator T(GenS<T> s) { Flag = 2; return default(T); } } class Program { public static void Main() { int? int_a1 = 1; GenS<int>? s28 = new GenS<int>(); // Due to related bug dev10: 742047 is won't fix // so expects the code will call explicit conversion operator int? result28 = s28 ?? int_a1; Console.WriteLine(GenS<int>.Flag); } } "; // Native compiler picks explicit conversion - print 3 CompileAndVerify(source, expectedOutput: "2"); } [Fact, WorkItem(529362, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529362")] public void TestNullCoalescingOverImplicitExplicitUDC_2() { string source = @"using System; struct S { public static explicit operator int?(S? s) { Console.WriteLine(""Explicit""); return 3; } public static implicit operator int(S? s) { Console.WriteLine(""Implicit""); return 2; } } class Program { public static void Main() { int? nn = -1; S? s = new S(); int? ret = s ?? nn; } } "; // Native compiler picks explicit conversion CompileAndVerify(source, expectedOutput: "Implicit"); } [Fact, WorkItem(529363, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529363")] public void AssignmentNullCoalescingOperator() { string source = @"using System; class NullCoalescingTest { public static void Main() { int? a; int c; var x = (a = null) ?? (c = 123); Console.WriteLine(c); } } "; // Native compiler no error (print -123) CreateCompilation(source).VerifyDiagnostics( // (10,27): error CS0165: Use of unassigned local variable 'c' // Console.WriteLine(c); Diagnostic(ErrorCode.ERR_UseDefViolation, "c").WithArguments("c"), // (7,14): warning CS0219: The variable 'a' is assigned but its value is never used // int? a; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "a").WithArguments("a")); } [Fact, WorkItem(529464, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529464")] public void MultiDimensionArrayWithDiffTypeIndexDevDiv31328() { var text = @" class A { public static void Main() { byte[,] arr = new byte[1, 1]; ulong i1 = 0; int i2 = 1; arr[i1, i2] = 127; // Dev10 CS0266 } } "; // Dev10 Won't fix bug#31328 for md array with different types' index and involving ulong // CS0266: Cannot implicitly convert type 'ulong' to 'int'. ... CreateCompilation(text).VerifyDiagnostics(); } [Fact] public void PointerArithmetic_SubtractNullLiteral() { var text = @" unsafe class C { long M(int* p) { return p - null; //Dev10 reports CS0019 } } "; // Dev10: the null literal is treated as though it is converted to void*, making the subtraction illegal (ExpressionBinder::GetPtrBinOpSigs). // Roslyn: the null literal is converted to int*, making the subtraction legal. CreateCompilation(text, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); } [Fact] public void CS0181ERR_BadAttributeParamType_Nullable() { var text = @" [Boom] class Boom : System.Attribute { public Boom(int? x = 0) { } static void Main() { typeof(Boom).GetCustomAttributes(true); } } "; // Roslyn: error CS0181: Attribute constructor parameter 'x' has type 'int?', which is not a valid attribute parameter type // Dev10/11: no error, but throw at runtime - System.Reflection.CustomAttributeFormatException CreateCompilation(text).VerifyDiagnostics( Diagnostic(ErrorCode.ERR_BadAttributeParamType, "Boom").WithArguments("x", "int?")); } /// <summary> /// When determining whether the LHS of a null-coalescing operator (??) is non-null, the native compiler strips off casts. /// /// We have decided not to reproduce this behavior. /// </summary> [Fact] public void CastOnLhsOfConditionalOperator() { var text = @" class C { static void Main(string[] args) { int i; int? j = (int?)1 ?? i; //dev10 accepts, since it treats the RHS as unreachable. int k; int? l = ((int?)1 ?? j) ?? k; // If the LHS of the LHS is non-null, then the LHS should be non-null, but dev10 only handles casts. int m; int? n = ((int?)1).HasValue ? ((int?)1).Value : m; //dev10 does not strip casts in a comparable conditional operator } } "; // Roslyn: error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('object') // Dev10/11: no error CreateCompilation(text).VerifyDiagnostics( // This is new in Roslyn. // (7,29): error CS0165: Use of unassigned local variable 'i' // int? j = (int?)1 ?? i; //dev10 accepts, since it treats the RHS as unreachable. Diagnostic(ErrorCode.ERR_UseDefViolation, "i").WithArguments("i"), // These match Dev10. // (10,36): error CS0165: Use of unassigned local variable 'k' // int? l = ((int?)1 ?? j) ?? k; // If the LHS of the LHS is non-null, then the LHS should be non-null, but dev10 only handles casts. Diagnostic(ErrorCode.ERR_UseDefViolation, "k").WithArguments("k"), // (13,57): error CS0165: Use of unassigned local variable 'm' // int? n = ((int?)1).HasValue ? ((int?)1).Value : m; //dev10 does not strip casts in a comparable conditional operator Diagnostic(ErrorCode.ERR_UseDefViolation, "m").WithArguments("m")); } [WorkItem(529974, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529974")] [Fact] public void TestCollisionForLoopControlVariable() { var source = @" namespace Microsoft.Test.XmlGen.Protocols.Saml2 { using System; using System.Collections.Generic; public class ProxyRestriction { XmlGenIntegerAttribute count; private List<XmlGenAttribute> Attributes { get; set; } public ProxyRestriction() { for (int count = 0; count < 10; count++) { } for (int i = 0; i < this.Attributes.Count; i++) { XmlGenAttribute attribute = this.Attributes[i]; if (attribute.LocalName == null) { if (count is XmlGenIntegerAttribute) { count = (XmlGenIntegerAttribute)attribute; } else { count = new XmlGenIntegerAttribute(attribute); this.Attributes[i] = count; } break; } } if (count == null) { this.Attributes.Add(new XmlGenIntegerAttribute(String.Empty, null, String.Empty, -1, false)); } } } internal class XmlGenAttribute { public object LocalName { get; internal set; } } internal class XmlGenIntegerAttribute : XmlGenAttribute { public XmlGenIntegerAttribute(string empty1, object count, string empty2, int v, bool isPresent) { } public XmlGenIntegerAttribute(XmlGenAttribute attribute) { } } } public class Program { public static void Main() { } }"; // Dev11 reported no errors for the above repro and allowed the name 'count' to bind to different // variables within the same declaration space. According to the old spec the error should be reported. // In Roslyn the single definition rule is relaxed and we do not give an error, but for a different reason. CreateCompilation(source).VerifyDiagnostics(); } [Fact, WorkItem(530301, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530301")] public void NoMore_CS0458WRN_AlwaysNull02() { CreateCompilation( @" public class Test { const bool ct = true; public static int Main() { var a = (true & null) ?? null; // CS0458 if (((null & true) == null)) // CS0458 return 0; var b = !(null | false); // CS0458 if ((false | null) != null) // CS0458 return 1; const bool cf = false; var d = ct & null ^ null; // CS0458 - Roslyn Warn this ONLY d ^= !(null | cf); // CS0458 return -1; } } ") // We decided to not report WRN_AlwaysNull in some cases. .VerifyDiagnostics( // Diagnostic(ErrorCode.WRN_AlwaysNull, "true & null").WithArguments("bool?"), // Diagnostic(ErrorCode.WRN_AlwaysNull, "null & true").WithArguments("bool?"), // Diagnostic(ErrorCode.WRN_AlwaysNull, "null | false").WithArguments("bool?"), // Diagnostic(ErrorCode.WRN_AlwaysNull, "false | null").WithArguments("bool?"), Diagnostic(ErrorCode.WRN_AlwaysNull, "ct & null ^ null").WithArguments("bool?") //, // Diagnostic(ErrorCode.WRN_AlwaysNull, "null | cf").WithArguments("bool?") ); } [WorkItem(530403, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530403")] [Fact] public void CS0135_local_param_cannot_be_declared() { // Dev11 missed this error. The issue is that an a is a field of c, and then it is a local in parts of d. // by then referring to the field without the this keyword, it should be flagged as declaring a competing variable (as it is confusing). var text = @" using System; public class @c { int a = 0; void d(bool b) { if(b) { int a = 1; Console.WriteLine(a); } else { a = 2; } a = 3; Console.WriteLine(a); } } "; var comp = CreateCompilation(text); // In Roslyn the single definition rule is relaxed and we do not give an error. comp.VerifyDiagnostics(); } [ConditionalFact(typeof(WindowsDesktopOnly), Reason = "https://github.com/dotnet/roslyn/issues/30160")] [WorkItem(530518, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530518")] public void ExpressionTreeExplicitOpVsConvert() { var text = @" using System; using System.Linq; using System.Linq.Expressions; class Test { public static explicit operator int(Test x) { return 1; } static void Main() { Expression<Func<Test, long?>> testExpr1 = x => (long?)x; Console.WriteLine(testExpr1); Expression<Func<Test, decimal?>> testExpr2 = x => (decimal?)x; Console.WriteLine(testExpr2); } } "; // Native Compiler: x => Convert(Convert(op_Explicit(x))) CompileAndVerify(text, expectedOutput: @"x => Convert(Convert(Convert(x))) x => Convert(Convert(Convert(x))) "); } [WorkItem(530531, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530531")] [ConditionalFact(typeof(WindowsDesktopOnly), Reason = "https://github.com/dotnet/roslyn/issues/30160")] public void ExpressionTreeNoCovertForIdentityConversion() { var source = @" using System; using System.Linq; using System.Linq.Expressions; class Test { static void Main() { Expression<Func<Guid, bool>> e = (x) => x != null; Console.WriteLine(e); Console.WriteLine(e.Compile()(default(Guid))); } } "; // Native compiler: x => (Convert(x) != Convert(null)) CompileAndVerify(source, expectedOutput: @"x => (Convert(x) != null) True "); } [Fact, WorkItem(530548, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530548")] public void CS0219WRN_UnreferencedVarAssg_RHSMidRefType() { string source = @" public interface Base { } public struct Derived : Base { } public class Test { public static void Main() { var b1 = new Derived(); // Both Warning CS0219 var b2 = (Base)new Derived(); // Both NO Warn (reference type) var b3 = (Derived)((Base)new Derived()); // Roslyn Warning CS0219 } } "; // Native compiler no error (print -123) CreateCompilation(source).VerifyDiagnostics( // (8,13): warning CS0219: The variable 'b1' is assigned but its value is never used // var b1 = new Derived(); // Both Warning CS0219 Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "b1").WithArguments("b1"), // (10,13): warning CS0219: The variable 'b3' is assigned but its value is never used // var b3 = (Derived)((Base)new Derived()); // Roslyn Warning CS0219 Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "b3").WithArguments("b3")); } [Fact, WorkItem(530556, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530556")] public void NoCS0591ERR_InvalidAttributeArgument() { string source = @" using System; [AttributeUsage(AttributeTargets.All + 0xFFFFFF)] class MyAtt : Attribute { } [AttributeUsage((AttributeTargets)0xffff)] class MyAtt1 : Attribute { } public class Test {} "; // Native compiler error CS0591: Invalid value for argument to 'AttributeUsage' attribute CreateCompilation(source).VerifyDiagnostics(); } [Fact, WorkItem(530586, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530586")] public void ThrowOnceInIteratorFinallyBlock() { string source = @" //<Title> Finally block runs twice in iterator</Title> //<RelatedBug>Dev10:473561-->8444?</RelatedBug> using System; using System.Collections; class Program { public static void Main() { var demo = new test(); try { foreach (var x in demo.Goo()) { } } catch (Exception) { Console.Write(""EX ""); } Console.WriteLine(demo.count); } class test { public int count = 0; public IEnumerable Goo() { try { yield return null; try { yield break; } catch { } } finally { Console.Write(""++ ""); ++count; throw new Exception(); } } } } "; // Native print "++ ++ EX 2" var verifier = CompileAndVerify(source, expectedOutput: " ++ EX 1"); // must not load "<>4__this" verifier.VerifyIL("Program.test.<Goo>d__1.System.Collections.IEnumerator.MoveNext()", @" { // Code size 101 (0x65) .maxstack 2 .locals init (bool V_0, int V_1) .try { IL_0000: ldarg.0 IL_0001: ldfld ""int Program.test.<Goo>d__1.<>1__state"" IL_0006: stloc.1 IL_0007: ldloc.1 IL_0008: brfalse.s IL_0012 IL_000a: ldloc.1 IL_000b: ldc.i4.1 IL_000c: beq.s IL_0033 IL_000e: ldc.i4.0 IL_000f: stloc.0 IL_0010: leave.s IL_0063 IL_0012: ldarg.0 IL_0013: ldc.i4.m1 IL_0014: stfld ""int Program.test.<Goo>d__1.<>1__state"" IL_0019: ldarg.0 IL_001a: ldc.i4.s -3 IL_001c: stfld ""int Program.test.<Goo>d__1.<>1__state"" IL_0021: ldarg.0 IL_0022: ldnull IL_0023: stfld ""object Program.test.<Goo>d__1.<>2__current"" IL_0028: ldarg.0 IL_0029: ldc.i4.1 IL_002a: stfld ""int Program.test.<Goo>d__1.<>1__state"" IL_002f: ldc.i4.1 IL_0030: stloc.0 IL_0031: leave.s IL_0063 IL_0033: ldarg.0 IL_0034: ldc.i4.s -3 IL_0036: stfld ""int Program.test.<Goo>d__1.<>1__state"" .try { IL_003b: ldc.i4.0 IL_003c: stloc.0 IL_003d: leave.s IL_004a } catch object { IL_003f: pop IL_0040: leave.s IL_0042 } IL_0042: ldarg.0 IL_0043: call ""void Program.test.<Goo>d__1.<>m__Finally1()"" IL_0048: br.s IL_0052 IL_004a: ldarg.0 IL_004b: call ""void Program.test.<Goo>d__1.<>m__Finally1()"" IL_0050: leave.s IL_0063 IL_0052: leave.s IL_005b } fault { IL_0054: ldarg.0 IL_0055: call ""void Program.test.<Goo>d__1.Dispose()"" IL_005a: endfinally } IL_005b: ldarg.0 IL_005c: call ""void Program.test.<Goo>d__1.Dispose()"" IL_0061: ldc.i4.1 IL_0062: stloc.0 IL_0063: ldloc.0 IL_0064: ret } "); // must load "<>4__this" verifier.VerifyIL("Program.test.<Goo>d__1.<>m__Finally1()", @" { // Code size 42 (0x2a) .maxstack 3 IL_0000: ldarg.0 IL_0001: ldc.i4.m1 IL_0002: stfld ""int Program.test.<Goo>d__1.<>1__state"" IL_0007: ldarg.0 IL_0008: ldfld ""Program.test Program.test.<Goo>d__1.<>4__this"" IL_000d: ldstr ""++ "" IL_0012: call ""void System.Console.Write(string)"" IL_0017: dup IL_0018: ldfld ""int Program.test.count"" IL_001d: ldc.i4.1 IL_001e: add IL_001f: stfld ""int Program.test.count"" IL_0024: newobj ""System.Exception..ctor()"" IL_0029: throw } "); } [Fact, WorkItem(530587, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530587")] public void NoFormatCharInIDEqual() { string source = @" #define A using System; class Program { static int Main() { int x = 0; #if A == A\uFFFB x=1; #endif Console.Write(x); return x; } } "; CompileAndVerify(source, expectedOutput: "1"); // Native print 0 } [Fact, WorkItem(530614, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530614")] public void CS1718WRN_ComparisonToSelf_Roslyn() { string source = @" enum @esbyte : sbyte { e0, e1 }; public class z_1495j12 { public static void Main() { if (esbyte.e0 == esbyte.e0) { System.Console.WriteLine(""T""); } }} "; // Native compiler no warn CreateCompilation(source).VerifyDiagnostics( // (7,5): warning CS1718: Comparison made to same variable; did you mean to compare something else? Diagnostic(ErrorCode.WRN_ComparisonToSelf, "esbyte.e0 == esbyte.e0")); } [Fact, WorkItem(530629, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530629")] public void CS0414WRN_UnreferencedFieldAssg_Roslyn() { string source = @" namespace VS7_336319 { public sealed class PredefinedTypes { public class Kind { public static int Decimal; } } public class ExpressionBinder { private static PredefinedTypes PredefinedTypes = null; private void Goo() { if (0 == (int)PredefinedTypes.Kind.Decimal) { } } } } "; // Native compiler no warn CreateCompilation(source).VerifyDiagnostics( // (10,40): warning CS0414: The field 'VS7_336319.ExpressionBinder.PredefinedTypes' is assigned but its value is never used // private static PredefinedTypes PredefinedTypes = null; Diagnostic(ErrorCode.WRN_UnreferencedFieldAssg, "PredefinedTypes").WithArguments("VS7_336319.ExpressionBinder.PredefinedTypes")); } [WorkItem(530666, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530666")] [ConditionalFact(typeof(WindowsDesktopOnly), Reason = "https://github.com/dotnet/roslyn/issues/30160")] public void ExpressionTreeWithNullableUDCandOperator() { string source = @" using System; using System.Linq.Expressions; struct B { public static implicit operator int?(B x) { return 1; } public static int operator +(B x, int y) { return 2 + y; } static int Main() { Expression<Func<B, int?>> f = x => x + x; var ret = f.Compile()(new B()); Console.WriteLine(ret); return ret.Value - 3; } } "; // Native compiler throw CompileAndVerify(source, expectedOutput: "3"); } [Fact, WorkItem(530696, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530696")] public void CS0121Err_AmbiguousMethodCall() { string source = @" class G<T> { } class C { static void M(params double[] x) { System.Console.WriteLine(1); } static void M(params G<int>[] x) { System.Console.WriteLine(2); } static void Main() { M(); } } "; CreateCompilation(source).VerifyDiagnostics( // (15,13): error CS0121: The call is ambiguous between the following methods or properties: 'C.M(params double[])' and 'C.M(params G<int>[])' // M(); Diagnostic(ErrorCode.ERR_AmbigCall, "M").WithArguments("C.M(params double[])", "C.M(params G<int>[])")); } [Fact, WorkItem(530653, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530653")] public void RepeatedObsoleteWarnings() { // <quote source="Srivatsn's comments from bug 16642"> // Inside a method body if you access a static field twice thus: // // var x = ObsoleteType.field1; // var y = ObsoleteType.field1; // // then the native compiler reports ObsoleteType as obsolete only once. This is because the native compiler caches // the lookup of type names for certain cases and doesn't report errors on the second lookup as that just comes // from the cache. Note how I said caches sometimes. If you simply say - // // var x= new ObsoleteType(); // var y = new ObsoleteType(); // // Then the native compiler reports the error twice. I don't think we should replicate this in Roslyn. Note however // that this is a breaking change because if the first line had been #pragma disabled, then the code would compile // without warnings in Dev11 but we will report warnings. I think it's a corner enough scenario and the native // behavior is quirky enough to warrant a break. // </quote> CompileAndVerify(@" using System; [Obsolete] public class ObsoleteType { public static readonly int field = 0; } public class Program { public static void Main() { #pragma warning disable 0612 var x = ObsoleteType.field; #pragma warning restore 0612 var y = ObsoleteType.field; // In Dev11, this line doesn't produce a warning. } }").VerifyDiagnostics( // (15,17): warning CS0612: 'ObsoleteType' is obsolete // var y = ObsoleteType.field; Diagnostic(ErrorCode.WRN_DeprecatedSymbol, "ObsoleteType").WithArguments("ObsoleteType")); } [Fact, WorkItem(530303, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530303")] public void TestReferenceResolution() { var cs1Compilation = CreateCSharpCompilation("CS1", @"public class CS1 {}", compilationOptions: TestOptions.ReleaseDll); var cs1Verifier = CompileAndVerify(cs1Compilation); cs1Verifier.VerifyDiagnostics(); var cs2Compilation = CreateCSharpCompilation("CS2", @"public class CS2<T> {}", compilationOptions: TestOptions.ReleaseDll, referencedCompilations: new Compilation[] { cs1Compilation }); var cs2Verifier = CompileAndVerify(cs2Compilation); cs2Verifier.VerifyDiagnostics(); var cs3Compilation = CreateCSharpCompilation("CS3", @"public class CS3 : CS2<CS1> {}", compilationOptions: TestOptions.ReleaseDll, referencedCompilations: new Compilation[] { cs1Compilation, cs2Compilation }); var cs3Verifier = CompileAndVerify(cs3Compilation); cs3Verifier.VerifyDiagnostics(); var cs4Compilation = CreateCSharpCompilation("CS4", @"public class Program { static void Main() { System.Console.WriteLine(typeof(CS3)); } }", compilationOptions: TestOptions.ReleaseExe, referencedCompilations: new Compilation[] { cs2Compilation, cs3Compilation }); cs4Compilation.VerifyDiagnostics(); } [Fact, WorkItem(531014, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/531014")] public void TestVariableAndTypeNameClashes() { CompileAndVerify(@" using System; public class Class1 { internal class A4 { internal class B { } internal static string F() { return ""A4""; } } internal class A5 { internal class B { } internal static string F() { return ""A5""; } } internal class A6 { internal class B { } internal static string F() { return ""A6""; } } internal delegate void D(); // Check the weird E.M cases. internal class Outer2 { internal static void F(A4 A4) { A5 A5; const A6 A6 = null; Console.WriteLine(typeof(A4.B)); Console.WriteLine(typeof(A5.B)); Console.WriteLine(typeof(A6.B)); Console.WriteLine(A4.F()); Console.WriteLine(A5.F()); Console.WriteLine(A6.F()); Console.WriteLine(default(A4) == null); Console.WriteLine(default(A5) == null); Console.WriteLine(default(A6) == null); } } }").VerifyDiagnostics( // Breaking Change: See bug 17395. Dev11 had a bug because of which it didn't report the below warnings. // (13,16): warning CS0168: The variable 'A5' is declared but never used // A5 A5; const A6 A6 = null; Diagnostic(ErrorCode.WRN_UnreferencedVar, "A5").WithArguments("A5"), // (13,29): warning CS0219: The variable 'A6' is assigned but its value is never used // A5 A5; const A6 A6 = null; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "A6").WithArguments("A6")); } [WorkItem(530584, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530584")] [Fact] public void NotRuntimeAmbiguousBecauseOfReturnTypes() { var source = @" using System; class Base<T, S> { public virtual int Goo(ref S x) { return 0; } public virtual string Goo(out T x) { x = default(T); return ""Base.Out""; } } class Derived : Base<int, int> { public override string Goo(out int x) { x = 0; return ""Derived.Out""; } static void Main() { int x; Console.WriteLine(new Derived().Goo(out x)); } } "; // BREAK: Dev11 reports WRN_MultipleRuntimeOverrideMatches, but there // is no runtime ambiguity because the return types differ. CompileAndVerify(source, expectedOutput: "Derived.Out"); } [WorkItem(695311, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/695311")] [Fact] public void NestedCollectionInitializerOnGenericProperty() { var libSource = @" using System.Collections; public interface IAdd { void Add(object o); } public struct S : IEnumerable, IAdd { private ArrayList list; public void Add(object o) { list = list ?? new ArrayList(); list.Add(o); } public IEnumerator GetEnumerator() { return (list ?? new ArrayList()).GetEnumerator(); } } public class C : IEnumerable, IAdd { private readonly ArrayList list = new ArrayList(); public void Add(object o) { list.Add(o); } public IEnumerator GetEnumerator() { return list.GetEnumerator(); } } public class Wrapper<T> : IEnumerable where T : IEnumerable, new() { public Wrapper() { this.Item = new T(); } public T Item { get; private set; } public IEnumerator GetEnumerator() { return Item.GetEnumerator(); } } public static class Util { public static int Count(IEnumerable i) { int count = 0; foreach (var v in i) count++; return count; } } "; var libRef = CreateCompilation(libSource, assemblyName: "lib").EmitToImageReference(); { var source = @" using System; using System.Collections; class Test { static void Main() { Console.Write(Util.Count(Goo<S>())); Console.Write(Util.Count(Goo<C>())); } static Wrapper<T> Goo<T>() where T : IEnumerable, IAdd, new() { return new Wrapper<T> { Item = { 1, 2, 3} }; } } "; // As in dev11. var comp = CreateCompilation(source, new[] { libRef }, TestOptions.ReleaseExe); CompileAndVerify(comp, expectedOutput: "03"); } { var source = @" using System; using System.Collections; class Test { static void Main() { Console.Write(Util.Count(Goo<C>())); } static Wrapper<T> Goo<T>() where T : class, IEnumerable, IAdd, new() { return new Wrapper<T> { Item = { 1, 2, 3} }; } } "; // As in dev11. // NOTE: The spec will likely be updated to make this illegal. var comp = CreateCompilation(source, new[] { libRef }, TestOptions.ReleaseExe); var verifier = CompileAndVerify(comp, expectedOutput: "3"); verifier.VerifyIL("Test.Goo<T>()", @" { // Code size 72 (0x48) .maxstack 3 IL_0000: newobj ""Wrapper<T>..ctor()"" IL_0005: dup IL_0006: callvirt ""T Wrapper<T>.Item.get"" IL_000b: box ""T"" IL_0010: ldc.i4.1 IL_0011: box ""int"" IL_0016: callvirt ""void IAdd.Add(object)"" IL_001b: dup IL_001c: callvirt ""T Wrapper<T>.Item.get"" IL_0021: box ""T"" IL_0026: ldc.i4.2 IL_0027: box ""int"" IL_002c: callvirt ""void IAdd.Add(object)"" IL_0031: dup IL_0032: callvirt ""T Wrapper<T>.Item.get"" IL_0037: box ""T"" IL_003c: ldc.i4.3 IL_003d: box ""int"" IL_0042: callvirt ""void IAdd.Add(object)"" IL_0047: ret } "); } { var source = @" using System; using System.Collections; class Test { static void Main() { Console.Write(Util.Count(Goo<S>())); } static Wrapper<T> Goo<T>() where T : struct, IEnumerable, IAdd { return new Wrapper<T> { Item = { 1, 2, 3} }; } } "; // BREAK: dev11 compiles and prints "0" var comp = CreateCompilation(source, new[] { libRef }, TestOptions.ReleaseExe); comp.VerifyDiagnostics( // (15,33): error CS1918: Members of property 'Wrapper<T>.Item' of type 'T' cannot be assigned with an object initializer because it is of a value type // return new Wrapper<T> { Item = { 1, 2, 3} }; Diagnostic(ErrorCode.ERR_ValueTypePropertyInObjectInitializer, "Item").WithArguments("Wrapper<T>.Item", "T")); } } [Fact, WorkItem(770424, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/770424"), WorkItem(1079034, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1079034")] public void UserDefinedShortCircuitingOperators() { var source = @" public class Base { public static bool operator true(Base x) { System.Console.Write(""Base.op_True""); return x != null; } public static bool operator false(Base x) { System.Console.Write(""Base.op_False""); return x == null; } } public class Derived : Base { public static Derived operator&(Derived x, Derived y) { return x; } public static Derived operator|(Derived x, Derived y) { return y; } static void Main() { Derived d = new Derived(); var b = (d && d) || d; } } "; CompileAndVerify(source, expectedOutput: "Base.op_FalseBase.op_True"); } } }