// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.IO; using System.Linq; using System.Text; using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.CSharp.Test.Utilities; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.Test.Utilities; using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { public class LambdaTests : CompilingTestBase { [Fact, WorkItem(608181, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/608181")] public void BadInvocationInLambda() { var src = @" using System; using System.Linq.Expressions; class C { Expression> e = x => new object[](x); }"; var comp = CreateCompilationWithMscorlib40AndSystemCore(src); comp.VerifyDiagnostics( // (7,52): error CS1586: Array creation must have array size or array initializer // Expression> e = x => new object[](x); Diagnostic(ErrorCode.ERR_MissingArraySize, "[]")); } [Fact] public void TestLambdaErrors01() { var comp = CreateCompilationWithMscorlib40AndSystemCore(@" using System; using System.Linq.Expressions; namespace System.Linq.Expressions { public class Expression {} } class C { delegate void D1(ref int x, out int y, int z); delegate void D2(out int x); void M() { int q1 = ()=>1; int q2 = delegate { return 1; }; Func q3 = x3=>1; Func q4 = (System.Itn23 x4)=>1; // type mismatch error should be suppressed on error type Func q5 = (System.Duobel x5)=>1; // but arity error should not be suppressed on error type D1 q6 = (double x6, ref int y6, ref int z6)=>1; // COMPATIBILITY: The C# 4 compiler produces two errors: // // error CS1676: Parameter 2 must be declared with the 'out' keyword // error CS1688: Cannot convert anonymous method block without a parameter list // to delegate type 'D1' because it has one or more out parameters // // This seems redundant (because there is no 'parameter 2' in the source code) // I propose that we eliminate the first error. D1 q7 = delegate {}; Frob q8 = ()=>{}; D2 q9 = x9=>{}; D1 q10 = (x10,y10,z10)=>{}; // COMPATIBILITY: The C# 4 compiler produces two errors: // // error CS0127: Since 'System.Action' returns void, a return keyword must // not be followed by an object expression // // error CS1662: Cannot convert lambda expression to delegate type 'System.Action' // because some of the return types in the block are not implicitly convertible to // the delegate return type // // The problem is adequately characterized by the first message; I propose we // eliminate the second, which seems both redundant and wrong. Action q11 = ()=>{ return 1; }; Action q12 = ()=>1; Func q13 = ()=>{ if (false) return 1; }; Func q14 = ()=>123.456; // Note that the type error is still an error even if the offending // return is unreachable. Func q15 = ()=>{if (false) return 1m; else return 0; }; // In the native compiler these errors were caught at parse time. In Roslyn, these are now semantic // analysis errors. See changeset 1674 for details. Action q16 = delegate (params int[] p) { }; Action q17 = (params string[] s)=>{}; Action q18 = (int x, params double[] s)=>{}; object q19 = new Action( (int x)=>{} ); Expression ex1 = ()=>1; } }"); comp.VerifyDiagnostics( // (16,18): error CS1660: Cannot convert lambda expression to type 'int' because it is not a delegate type // int q1 = ()=>1; Diagnostic(ErrorCode.ERR_AnonMethToNonDel, "()=>1").WithArguments("lambda expression", "int").WithLocation(16, 18), // (17,18): error CS1660: Cannot convert anonymous method to type 'int' because it is not a delegate type // int q2 = delegate { return 1; }; Diagnostic(ErrorCode.ERR_AnonMethToNonDel, "delegate { return 1; }").WithArguments("anonymous method", "int").WithLocation(17, 18), // (18,24): error CS1593: Delegate 'Func' does not take 1 arguments // Func q3 = x3=>1; Diagnostic(ErrorCode.ERR_BadDelArgCount, "x3=>1").WithArguments("System.Func", "1").WithLocation(18, 24), // (19,37): error CS0234: The type or namespace name 'Itn23' does not exist in the namespace 'System' (are you missing an assembly reference?) // Func q4 = (System.Itn23 x4)=>1; // type mismatch error should be suppressed on error type Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "Itn23").WithArguments("Itn23", "System").WithLocation(19, 37), // (20,35): error CS0234: The type or namespace name 'Duobel' does not exist in the namespace 'System' (are you missing an assembly reference?) // Func q5 = (System.Duobel x5)=>1; // but arity error should not be suppressed on error type Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "Duobel").WithArguments("Duobel", "System").WithLocation(20, 35), // (20,27): error CS1593: Delegate 'Func' does not take 1 arguments // Func q5 = (System.Duobel x5)=>1; // but arity error should not be suppressed on error type Diagnostic(ErrorCode.ERR_BadDelArgCount, "(System.Duobel x5)=>1").WithArguments("System.Func", "1").WithLocation(20, 27), // (21,17): error CS1661: Cannot convert lambda expression to delegate type 'C.D1' because the parameter types do not match the delegate parameter types // D1 q6 = (double x6, ref int y6, ref int z6)=>1; Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "(double x6, ref int y6, ref int z6)=>1").WithArguments("lambda expression", "C.D1").WithLocation(21, 17), // (21,25): error CS1678: Parameter 1 is declared as type 'double' but should be 'ref int' // D1 q6 = (double x6, ref int y6, ref int z6)=>1; Diagnostic(ErrorCode.ERR_BadParamType, "x6").WithArguments("1", "", "double", "ref ", "int").WithLocation(21, 25), // (21,37): error CS1676: Parameter 2 must be declared with the 'out' keyword // D1 q6 = (double x6, ref int y6, ref int z6)=>1; Diagnostic(ErrorCode.ERR_BadParamRef, "y6").WithArguments("2", "out").WithLocation(21, 37), // (21,49): error CS1677: Parameter 3 should not be declared with the 'ref' keyword // D1 q6 = (double x6, ref int y6, ref int z6)=>1; Diagnostic(ErrorCode.ERR_BadParamExtraRef, "z6").WithArguments("3", "ref").WithLocation(21, 49), // (32,17): error CS1688: Cannot convert anonymous method block without a parameter list to delegate type 'C.D1' because it has one or more out parameters // D1 q7 = delegate {}; Diagnostic(ErrorCode.ERR_CantConvAnonMethNoParams, "delegate {}").WithArguments("C.D1").WithLocation(32, 17), // (34,9): error CS0246: The type or namespace name 'Frob' could not be found (are you missing a using directive or an assembly reference?) // Frob q8 = ()=>{}; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Frob").WithArguments("Frob").WithLocation(34, 9), // (36,17): error CS1676: Parameter 1 must be declared with the 'out' keyword // D2 q9 = x9=>{}; Diagnostic(ErrorCode.ERR_BadParamRef, "x9").WithArguments("1", "out").WithLocation(36, 17), // (38,19): error CS1676: Parameter 1 must be declared with the 'ref' keyword // D1 q10 = (x10,y10,z10)=>{}; Diagnostic(ErrorCode.ERR_BadParamRef, "x10").WithArguments("1", "ref").WithLocation(38, 19), // (38,23): error CS1676: Parameter 2 must be declared with the 'out' keyword // D1 q10 = (x10,y10,z10)=>{}; Diagnostic(ErrorCode.ERR_BadParamRef, "y10").WithArguments("2", "out").WithLocation(38, 23), // (52,28): error CS8030: Anonymous function converted to a void returning delegate cannot return a value // Action q11 = ()=>{ return 1; }; Diagnostic(ErrorCode.ERR_RetNoObjectRequiredLambda, "return").WithLocation(52, 28), // (54,26): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement // Action q12 = ()=>1; Diagnostic(ErrorCode.ERR_IllegalStatement, "1").WithLocation(54, 26), // (56,42): warning CS0162: Unreachable code detected // Func q13 = ()=>{ if (false) return 1; }; Diagnostic(ErrorCode.WRN_UnreachableCode, "return").WithLocation(56, 42), // (56,27): error CS1643: Not all code paths return a value in lambda expression of type 'Func' // Func q13 = ()=>{ if (false) return 1; }; Diagnostic(ErrorCode.ERR_AnonymousReturnExpected, "=>").WithArguments("lambda expression", "System.Func").WithLocation(56, 27), // (58,29): error CS0266: Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?) // Func q14 = ()=>123.456; Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "123.456").WithArguments("double", "int").WithLocation(58, 29), // (58,29): error CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type // Func q14 = ()=>123.456; Diagnostic(ErrorCode.ERR_CantConvAnonMethReturns, "123.456").WithArguments("lambda expression").WithLocation(58, 29), // (62,51): error CS0266: Cannot implicitly convert type 'decimal' to 'double'. An explicit conversion exists (are you missing a cast?) // Func q15 = ()=>{if (false) return 1m; else return 0; }; Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "1m").WithArguments("decimal", "double").WithLocation(62, 51), // (62,51): error CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type // Func q15 = ()=>{if (false) return 1m; else return 0; }; Diagnostic(ErrorCode.ERR_CantConvAnonMethReturns, "1m").WithArguments("lambda expression").WithLocation(62, 51), // (62,44): warning CS0162: Unreachable code detected // Func q15 = ()=>{if (false) return 1m; else return 0; }; Diagnostic(ErrorCode.WRN_UnreachableCode, "return").WithLocation(62, 44), // (66,39): error CS1670: params is not valid in this context // Action q16 = delegate (params int[] p) { }; Diagnostic(ErrorCode.ERR_IllegalParams, "params int[] p").WithLocation(66, 39), // (67,33): error CS1670: params is not valid in this context // Action q17 = (params string[] s)=>{}; Diagnostic(ErrorCode.ERR_IllegalParams, "params string[] s").WithLocation(67, 33), // (68,45): error CS1670: params is not valid in this context // Action q18 = (int x, params double[] s)=>{}; Diagnostic(ErrorCode.ERR_IllegalParams, "params double[] s").WithLocation(68, 45), // (70,34): error CS1593: Delegate 'Action' does not take 1 arguments // object q19 = new Action( (int x)=>{} ); Diagnostic(ErrorCode.ERR_BadDelArgCount, "(int x)=>{}").WithArguments("System.Action", "1").WithLocation(70, 34), // (72,9): warning CS0436: The type 'Expression' in '' conflicts with the imported type 'Expression' in 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. Using the type defined in ''. // Expression ex1 = ()=>1; Diagnostic(ErrorCode.WRN_SameFullNameThisAggAgg, "Expression").WithArguments("", "System.Linq.Expressions.Expression", "System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "System.Linq.Expressions.Expression").WithLocation(72, 9), // (72,31): error CS0835: Cannot convert lambda to an expression tree whose type argument 'int' is not a delegate type // Expression ex1 = ()=>1; Diagnostic(ErrorCode.ERR_ExpressionTreeMustHaveDelegate, "()=>1").WithArguments("int").WithLocation(72, 31) ); } [Fact] // 5368 public void TestLambdaErrors02() { string code = @" class C { void M() { System.Func del = x => x + 1; } }"; var compilation = CreateCompilation(code); compilation.VerifyDiagnostics(); // no errors expected } [WorkItem(539538, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539538")] [Fact] public void TestLambdaErrors03() { string source = @" using System; interface I : IComparable> { } class C { static void Goo(Func> x) { } static void Goo(Func x) {} static void M() { Goo(() => null); } } "; CreateCompilation(source).VerifyDiagnostics( // (12,9): error CS0121: The call is ambiguous between the following methods or properties: 'C.Goo(Func>)' and 'C.Goo(Func)' // Goo(() => null); Diagnostic(ErrorCode.ERR_AmbigCall, "Goo").WithArguments("C.Goo(System.Func>)", "C.Goo(System.Func)").WithLocation(12, 9)); } [WorkItem(18645, "https://github.com/dotnet/roslyn/issues/18645")] [Fact] public void LambdaExpressionTreesErrors() { string source = @" using System; using System.Linq.Expressions; class C { void M() { Expression> ex1 = () => 1; Expression> ex2 = (double d) => 1; } } "; CreateCompilation(source).VerifyDiagnostics( // (9,41): error CS1593: Delegate 'Func' does not take 0 arguments // Expression> ex1 = () => 1; Diagnostic(ErrorCode.ERR_BadDelArgCount, "() => 1").WithArguments("System.Func", "0").WithLocation(9, 41), // (10,41): error CS1661: Cannot convert lambda expression to type 'Expression>' because the parameter types do not match the delegate parameter types // Expression> ex2 = (double d) => 1; Diagnostic(ErrorCode.ERR_CantConvAnonMethParams, "(double d) => 1").WithArguments("lambda expression", "System.Linq.Expressions.Expression>").WithLocation(10, 41), // (10,49): error CS1678: Parameter 1 is declared as type 'double' but should be 'int' // Expression> ex2 = (double d) => 1; Diagnostic(ErrorCode.ERR_BadParamType, "d").WithArguments("1", "", "double", "", "int").WithLocation(10, 49)); } [WorkItem(539976, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539976")] [Fact] public void LambdaArgumentToOverloadedDelegate() { var text = @"class W { delegate T Func(A0 a0); static int F(Func f) { return 0; } static int F(Func f) { return 1; } static int Main() { return F(c => c); } } "; var comp = CreateCompilation(Parse(text)); comp.VerifyDiagnostics(); } [WorkItem(528044, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528044")] [Fact] public void MissingReferenceInOverloadResolution() { var text1 = @" using System; public static class A { public static void Goo(Func func) { } public static void Goo(Func func) { } } public class B { public Uri GetUrl() { return null; } } public class C { public string GetUrl() { return null; } }"; var comp1 = CreateCompilationWithMscorlib40( new[] { Parse(text1) }, new[] { TestReferences.NetFx.v4_0_30319.System }); var text2 = @" class Program { static void Main() { A.Goo(x => x.GetUrl()); } } "; var comp2 = CreateCompilationWithMscorlib40( new[] { Parse(text2) }, new[] { new CSharpCompilationReference(comp1) }); Assert.Equal(0, comp2.GetDiagnostics().Count()); } [WorkItem(528047, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528047")] [Fact()] public void OverloadResolutionWithEmbeddedInteropType() { var text1 = @" using System; using System.Collections.Generic; using stdole; public static class A { public static void Goo(Func func) { System.Console.WriteLine(""X""); } public static void Goo(Func func) { System.Console.WriteLine(""Y""); } } public delegate void X(List addin); public delegate void Y(List addin); "; var comp1 = CreateCompilation( Parse(text1), new[] { TestReferences.SymbolsTests.NoPia.StdOle.WithEmbedInteropTypes(true) }, options: TestOptions.ReleaseDll); var text2 = @" public class Program { public static void Main() { A.Goo(() => delegate { }); } } "; var comp2 = CreateCompilation( Parse(text2), new MetadataReference[] { new CSharpCompilationReference(comp1), TestReferences.SymbolsTests.NoPia.StdOle.WithEmbedInteropTypes(true) }, options: TestOptions.ReleaseExe); CompileAndVerify(comp2, expectedOutput: "Y").Diagnostics.Verify(); var comp3 = CreateCompilation( Parse(text2), new MetadataReference[] { comp1.EmitToImageReference(), TestReferences.SymbolsTests.NoPia.StdOle.WithEmbedInteropTypes(true) }, options: TestOptions.ReleaseExe); CompileAndVerify(comp3, expectedOutput: "Y").Diagnostics.Verify(); } [WorkItem(6358, "DevDiv_Projects/Roslyn")] [Fact] public void InvalidExpressionInvolveLambdaOperator() { var text1 = @" class C { static void X() { int x=0; int y=0; if(x-=>*y) // CS1525 return; return; } } "; var comp = CreateCompilation(Parse(text1)); var errs = comp.GetDiagnostics(); Assert.True(0 < errs.Count(), "Diagnostics not empty"); Assert.True(0 < errs.Where(e => e.Code == 1525).Select(e => e).Count(), "Diagnostics contains CS1525"); } [WorkItem(540219, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540219")] [Fact] public void OverloadResolutionWithStaticType() { var vbSource = @" Imports System Namespace Microsoft.VisualBasic.CompilerServices Public NotInheritable Class StandardModuleAttribute Inherits System.Attribute Public Sub New() MyBase.New() End Sub End Class End Namespace Public Module M Sub Goo(x as Action(Of String)) End Sub Sub Goo(x as Action(Of GC)) End Sub End Module "; var vbProject = VisualBasic.VisualBasicCompilation.Create( "VBProject", references: new[] { MscorlibRef }, syntaxTrees: new[] { VisualBasic.VisualBasicSyntaxTree.ParseText(vbSource) }); var csSource = @" class Program { static void Main() { M.Goo(x => { }); } } "; var metadataStream = new MemoryStream(); var emitResult = vbProject.Emit(metadataStream, options: new EmitOptions(metadataOnly: true)); Assert.True(emitResult.Success); var csProject = CreateCompilation( Parse(csSource), new[] { MetadataReference.CreateFromImage(metadataStream.ToImmutable()) }); Assert.Equal(0, csProject.GetDiagnostics().Count()); } [Fact] public void OverloadResolutionWithStaticTypeError() { var vbSource = @" Imports System Namespace Microsoft.VisualBasic.CompilerServices Public NotInheritable Class StandardModuleAttribute Inherits System.Attribute Public Sub New() MyBase.New() End Sub End Class End Namespace Public Module M Public Dim F As Action(Of GC) End Module "; var vbProject = VisualBasic.VisualBasicCompilation.Create( "VBProject", references: new[] { MscorlibRef }, syntaxTrees: new[] { VisualBasic.VisualBasicSyntaxTree.ParseText(vbSource) }); var csSource = @" class Program { static void Main() { M.F = x=>{}; } } "; var vbMetadata = vbProject.EmitToArray(options: new EmitOptions(metadataOnly: true)); var csProject = CreateCompilation(Parse(csSource), new[] { MetadataReference.CreateFromImage(vbMetadata) }); var diagnostics = csProject.GetDiagnostics().Select(DumpDiagnostic); Assert.Equal(1, diagnostics.Count()); Assert.Equal("'x' error CS0721: 'GC': static types cannot be used as parameters", diagnostics.First()); } [WorkItem(540251, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540251")] [Fact] public void AttributesCannotBeUsedInAnonymousMethods() { var csSource = @" using System; class Program { static void Main() { const string message = ""The parameter is obsolete""; Action a = delegate ([ObsoleteAttribute(message)] int x) { }; } } "; var csProject = CreateCompilation(csSource); var emitResult = csProject.Emit(Stream.Null); Assert.False(emitResult.Success); Assert.True(emitResult.Diagnostics.Any()); // TODO: check error code } [WorkItem(540263, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540263")] [Fact] public void ErrorsInUnboundLambdas() { var csSource = @"using System; class Program { static void Main() { ((Func)delegate { return """"; })(); ((Func)delegate { })(); ((Func)delegate { 1 / 0; })(); } } "; CreateCompilation(csSource).VerifyDiagnostics( // (7,39): error CS0029: Cannot implicitly convert type 'string' to 'int' // ((Func)delegate { return ""; })(); Diagnostic(ErrorCode.ERR_NoImplicitConv, @"""""").WithArguments("string", "int").WithLocation(7, 39), // (7,39): error CS1662: Cannot convert anonymous method to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type // ((Func)delegate { return ""; })(); Diagnostic(ErrorCode.ERR_CantConvAnonMethReturns, @"""""").WithArguments("anonymous method").WithLocation(7, 39), // (8,21): error CS1643: Not all code paths return a value in anonymous method of type 'Func' // ((Func)delegate { })(); Diagnostic(ErrorCode.ERR_AnonymousReturnExpected, "delegate").WithArguments("anonymous method", "System.Func").WithLocation(8, 21), // (9,32): error CS0020: Division by constant zero // ((Func)delegate { 1 / 0; })(); Diagnostic(ErrorCode.ERR_IntDivByZero, "1 / 0").WithLocation(9, 32), // (9,32): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement // ((Func)delegate { 1 / 0; })(); Diagnostic(ErrorCode.ERR_IllegalStatement, "1 / 0").WithLocation(9, 32), // (9,21): error CS1643: Not all code paths return a value in anonymous method of type 'Func' // ((Func)delegate { 1 / 0; })(); Diagnostic(ErrorCode.ERR_AnonymousReturnExpected, "delegate").WithArguments("anonymous method", "System.Func").WithLocation(9, 21) ); } [WorkItem(540181, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/540181")] [Fact] public void ErrorInLambdaArgumentList() { var csSource = @"using System; class Program { public Program(string x) : this(() => x) { } static void Main(string[] args) { ((Action)(f => Console.WriteLine(f)))(nulF); } }"; CreateCompilation(csSource).VerifyDiagnostics( // (5,37): error CS1660: Cannot convert lambda expression to type 'string' because it is not a delegate type Diagnostic(ErrorCode.ERR_AnonMethToNonDel, @"() => x").WithArguments("lambda expression", "string"), // (8,55): error CS0103: The name 'nulF' does not exist in the current context Diagnostic(ErrorCode.ERR_NameNotInContext, @"nulF").WithArguments("nulF")); } [WorkItem(541725, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541725")] [Fact] public void DelegateCreationIsNotStatement() { var csSource = @" delegate void D(); class Program { public static void Main(string[] args) { D d = () => new D(() => { }); new D(()=>{}); } }"; // Though it is legal to have an object-creation-expression, because it might be useful // for its side effects, a delegate-creation-expression is not allowed as a // statement expression. CreateCompilation(csSource).VerifyDiagnostics( // (7,21): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement // D d = () => new D(() => { }); Diagnostic(ErrorCode.ERR_IllegalStatement, "new D(() => { })"), // (8,9): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement // new D(()=>{}); Diagnostic(ErrorCode.ERR_IllegalStatement, "new D(()=>{})")); } [WorkItem(542336, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542336")] [Fact] public void ThisInStaticContext() { var csSource = @" delegate void D(); class Program { public static void Main(string[] args) { D d = () => { object o = this; }; } }"; CreateCompilation(csSource).VerifyDiagnostics( // (8,24): error CS0026: Keyword 'this' is not valid in a static property, static method, or static field initializer // object o = this; Diagnostic(ErrorCode.ERR_ThisInStaticMeth, "this") ); } [WorkItem(542431, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542431")] [Fact] public void LambdaHasMoreParametersThanDelegate() { var csSource = @" class C { static void Main() { System.Func f = new System.Func(r => 0); } }"; CreateCompilation(csSource).VerifyDiagnostics( // (6,51): error CS1593: Delegate 'System.Func' does not take 1 arguments Diagnostic(ErrorCode.ERR_BadDelArgCount, "r => 0").WithArguments("System.Func", "1")); } [Fact, WorkItem(529054, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529054")] public void LambdaInDynamicCall() { var source = @" public class Program { static void Main() { dynamic b = new string[] { ""AA"" }; bool exists = System.Array.Exists(b, o => o != ""BB""); } }"; CreateCompilation(source).VerifyDiagnostics( // (7,46): error CS1977: Cannot use a lambda expression as an argument to a dynamically dispatched operation without first casting it to a delegate or expression tree type. // bool exists = System.Array.Exists(b, o => o != "BB"); Diagnostic(ErrorCode.ERR_BadDynamicMethodArgLambda, @"o => o != ""BB""") ); } [Fact, WorkItem(529389, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529389")] public void ParenthesizedLambdaInCastExpression() { var source = @" using System; using System.Collections.Generic; class Program { static void Main() { int x = 1; byte y = (byte) (x + x); Func f1 = (() => { return 1; }); Func f2 = (Func) (() => { return 2; }); } } "; var tree = SyntaxFactory.ParseSyntaxTree(source); var comp = CreateCompilation(tree); var model = comp.GetSemanticModel(tree); ExpressionSyntax expr = tree.GetCompilationUnitRoot().DescendantNodes().OfType(). Where(e => e.Kind() == SyntaxKind.AddExpression).Single(); var tinfo = model.GetTypeInfo(expr); var conv = model.GetConversion(expr); // Not byte Assert.Equal("int", tinfo.Type.ToDisplayString()); var exprs = tree.GetCompilationUnitRoot().DescendantNodes().OfType(); expr = exprs.First(); tinfo = model.GetTypeInfo(expr); conv = model.GetConversion(expr); Assert.True(conv.IsAnonymousFunction, "LambdaConversion"); Assert.Null(tinfo.Type); var sym = model.GetSymbolInfo(expr).Symbol; Assert.NotNull(sym); Assert.Equal(SymbolKind.Method, sym.Kind); Assert.Equal(MethodKind.AnonymousFunction, (sym as MethodSymbol).MethodKind); expr = exprs.Last(); tinfo = model.GetTypeInfo(expr); conv = model.GetConversion(expr); Assert.True(conv.IsAnonymousFunction, "LambdaConversion"); Assert.Null(tinfo.Type); sym = model.GetSymbolInfo(expr).Symbol; Assert.NotNull(sym); Assert.Equal(SymbolKind.Method, sym.Kind); Assert.Equal(MethodKind.AnonymousFunction, (sym as MethodSymbol).MethodKind); } [WorkItem(544594, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544594")] [Fact] public void LambdaInEnumMemberDecl() { var csSource = @" public class TestClass { public enum Test { aa = ((System.Func)(() => 1))() } Test MyTest = Test.aa; public static void Main() { } } "; CreateCompilation(csSource).VerifyDiagnostics( // (4,29): error CS0133: The expression being assigned to 'TestClass.Test.aa' must be constant Diagnostic(ErrorCode.ERR_NotConstantExpression, "((System.Func)(() => 1))()").WithArguments("TestClass.Test.aa"), // (5,10): warning CS0414: The field 'TestClass.MyTest' is assigned but its value is never used Diagnostic(ErrorCode.WRN_UnreferencedFieldAssg, "MyTest").WithArguments("TestClass.MyTest")); } [WorkItem(544932, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544932")] [Fact] public void AnonymousLambdaInEnumSubtraction() { string source = @" class Test { enum E1 : byte { A = byte.MinValue, C = 1 } static void Main() { int j = ((System.Func)(() => E1.A))() - E1.C; System.Console.WriteLine(j); } } "; string expectedOutput = @"255"; CompileAndVerify(new[] { source }, expectedOutput: expectedOutput); } [WorkItem(545156, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545156")] [Fact] public void SpeculativelyBindOverloadResolution() { string source = @" using System; using System.Collections; using System.Collections.Generic; class Program { static void Main() { Goo(() => () => { var x = (IEnumerable)null; return x; }); } static void Goo(Func> x) { } static void Goo(Func> x) { } } "; var compilation = CreateCompilation(source); var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree); var invocation = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single(); // Used to throw a NRE because of the ExpressionSyntax's null SyntaxTree. model.GetSpeculativeSymbolInfo( invocation.SpanStart, SyntaxFactory.ParseExpression("Goo(() => () => { var x = null; return x; })"), // cast removed SpeculativeBindingOption.BindAsExpression); } [WorkItem(545343, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545343")] [Fact] public void LambdaUsingFieldInConstructor() { string source = @" using System; public class Derived { int field = 1; Derived() { int local = 2; // A lambda that captures a local and refers to an instance field. Action a = () => Console.WriteLine(""Local = {0}, Field = {1}"", local, field); // NullReferenceException if the ""this"" field of the display class hasn't been set. a(); } public static void Main() { Derived d = new Derived(); } }"; CompileAndVerify(source, expectedOutput: "Local = 2, Field = 1"); } [WorkItem(642222, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/642222")] [Fact] public void SpeculativelyBindOverloadResolutionAndInferenceWithError() { string source = @" using System;using System.Linq.Expressions; namespace IntellisenseBug { public class Program { void M(Mapper mapper) { // Intellisense is broken here when you type . after the x: mapper.Map(x => x/* */. } } public class Mapper { public void Map( Expression> from, Expression> to) { } } public class FromData { public int Int { get; set; } public string String { get; set; } } public class ToData { public int Id { get; set; } public string Name { get; set; } } }"; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); // We don't actually require any particular diagnostics, but these are what we get. compilation.VerifyDiagnostics( // (10,36): error CS1001: Identifier expected // mapper.Map(x => x/* */. Diagnostic(ErrorCode.ERR_IdentifierExpected, ""), // (10,36): error CS1026: ) expected // mapper.Map(x => x/* */. Diagnostic(ErrorCode.ERR_CloseParenExpected, ""), // (10,36): error CS1002: ; expected // mapper.Map(x => x/* */. Diagnostic(ErrorCode.ERR_SemicolonExpected, "") ); var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree); var xReference = tree .GetCompilationUnitRoot() .DescendantNodes() .OfType() .Where(e => e.ToFullString() == "x/* */") .Last(); var typeInfo = model.GetTypeInfo(xReference); Assert.NotNull(((TypeSymbol)typeInfo.Type).GetMember("String")); } [WorkItem(722288, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/722288")] [Fact] public void CompletionInLambdaInIncompleteInvocation() { string source = @" using System; using System.Linq.Expressions; public class SomeType { public string SomeProperty { get; set; } } public class IntelliSenseError { public static void Test1(Expression> expr) { Console.WriteLine(((MemberExpression)expr.Body).Member.Name); } public static void Test2(Expression> expr, bool additionalParameter) { Test1(expr); } public static void Main() { Test2(o => o/* */. } } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); // We don't actually require any particular diagnostics, but these are what we get. compilation.VerifyDiagnostics( // (21,37): error CS1001: Identifier expected // Test2(o => o/* */. Diagnostic(ErrorCode.ERR_IdentifierExpected, ""), // (21,37): error CS1026: ) expected // Test2(o => o/* */. Diagnostic(ErrorCode.ERR_CloseParenExpected, ""), // (21,37): error CS1002: ; expected // Test2(o => o/* */. Diagnostic(ErrorCode.ERR_SemicolonExpected, "") ); var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree); var oReference = tree .GetCompilationUnitRoot() .DescendantNodes() .OfType() .Where(e => e.ToFullString() == "o/* */") .Last(); var typeInfo = model.GetTypeInfo(oReference); Assert.NotNull(((TypeSymbol)typeInfo.Type).GetMember("SomeProperty")); } [WorkItem(871896, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/871896")] [Fact] public void Bug871896() { string source = @" using System.Threading; using System.Threading.Tasks; class TestDataPointBase { private readonly IVisualStudioIntegrationService integrationService; protected void TryGetDocumentId(CancellationToken token) { DocumentId documentId = null; if (!await Task.Run(() => this.integrationService.TryGetDocumentId(null, out documentId), token).ConfigureAwait(false)) { } } } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); var tree = compilation.SyntaxTrees.Single(); var model = compilation.GetSemanticModel(tree); var oReference = tree .GetCompilationUnitRoot() .DescendantNodes() .OfType() .OrderByDescending(s => s.SpanStart); foreach (var name in oReference) { CSharpExtensions.GetSymbolInfo(model, name); } // We should get a bunch of errors, but no asserts. compilation.VerifyDiagnostics( // (6,22): error CS0246: The type or namespace name 'IVisualStudioIntegrationService' could not be found (are you missing a using directive or an assembly reference?) // private readonly IVisualStudioIntegrationService integrationService; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "IVisualStudioIntegrationService").WithArguments("IVisualStudioIntegrationService").WithLocation(6, 22), // (9,9): error CS0246: The type or namespace name 'DocumentId' could not be found (are you missing a using directive or an assembly reference?) // DocumentId documentId = null; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "DocumentId").WithArguments("DocumentId").WithLocation(9, 9), // (10,25): error CS0117: 'System.Threading.Tasks.Task' does not contain a definition for 'Run' // if (!await Task.Run(() => this.integrationService.TryGetDocumentId(null, out documentId), token).ConfigureAwait(false)) Diagnostic(ErrorCode.ERR_NoSuchMember, "Run").WithArguments("System.Threading.Tasks.Task", "Run").WithLocation(10, 25), // (10,14): error CS4033: The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing its return type to 'Task'. // if (!await Task.Run(() => this.integrationService.TryGetDocumentId(null, out documentId), token).ConfigureAwait(false)) Diagnostic(ErrorCode.ERR_BadAwaitWithoutVoidAsyncMethod, "await Task.Run(() => this.integrationService.TryGetDocumentId(null, out documentId), token).ConfigureAwait(false)").WithLocation(10, 14), // (6,54): warning CS0649: Field 'TestDataPointBase.integrationService' is never assigned to, and will always have its default value null // private readonly IVisualStudioIntegrationService integrationService; Diagnostic(ErrorCode.WRN_UnassignedInternalField, "integrationService").WithArguments("TestDataPointBase.integrationService", "null").WithLocation(6, 54) ); } [Fact, WorkItem(960755, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/960755")] public void Bug960755_01() { var source = @" using System.Collections.Generic; class C { static void M(IList c) { var tmp = new C(); tmp.M((a, b) => c.Add); } } "; var tree = SyntaxFactory.ParseSyntaxTree(source); var comp = CreateCompilation(tree); var model = comp.GetSemanticModel(tree); var expr = (ExpressionSyntax)tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single().Body; var symbolInfo = model.GetSymbolInfo(expr); Assert.Null(symbolInfo.Symbol); Assert.Equal("void System.Collections.Generic.ICollection.Add(C item)", symbolInfo.CandidateSymbols.Single().ToTestDisplayString()); Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); } [Fact, WorkItem(960755, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/960755")] public void Bug960755_02() { var source = @" using System.Collections.Generic; class C { static void M(IList c) { int tmp = c.Add; } } "; var tree = SyntaxFactory.ParseSyntaxTree(source); var comp = CreateCompilation(tree); var model = comp.GetSemanticModel(tree); var expr = (ExpressionSyntax)tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single().Initializer.Value; var symbolInfo = model.GetSymbolInfo(expr); Assert.Null(symbolInfo.Symbol); Assert.Equal("void System.Collections.Generic.ICollection.Add(C item)", symbolInfo.CandidateSymbols.Single().ToTestDisplayString()); Assert.Equal(CandidateReason.OverloadResolutionFailure, symbolInfo.CandidateReason); } [Fact, WorkItem(960755, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/960755")] public void Bug960755_03() { var source = @" using System.Collections.Generic; class C { static void M(IList c) { var tmp = new C(); tmp.M((a, b) => c.Add); } static void M(System.Func> x) {} } "; var tree = SyntaxFactory.ParseSyntaxTree(source); var comp = CreateCompilation(tree); var model = comp.GetSemanticModel(tree); var expr = (ExpressionSyntax)tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single().Body; var symbolInfo = model.GetSymbolInfo(expr); Assert.Equal("void System.Collections.Generic.ICollection.Add(C item)", symbolInfo.Symbol.ToTestDisplayString()); Assert.Equal(0, symbolInfo.CandidateSymbols.Length); Assert.Equal(CandidateReason.None, symbolInfo.CandidateReason); } [Fact] public void RefLambdaInferenceMethodArgument() { var text = @" delegate ref int D(); class C { static void MD(D d) { } static int i = 0; static void M() { MD(() => ref i); MD(() => { return ref i; }); MD(delegate { return ref i; }); } } "; CreateCompilationWithMscorlib45(text).VerifyDiagnostics(); } [Fact] public void RefLambdaInferenceDelegateCreation() { var text = @" delegate ref int D(); class C { static int i = 0; static void M() { var d = new D(() => ref i); d = new D(() => { return ref i; }); d = new D(delegate { return ref i; }); } } "; CreateCompilationWithMscorlib45(text).VerifyDiagnostics(); } [Fact] public void RefLambdaInferenceOverloadedDelegateType() { var text = @" delegate ref int D(); delegate int E(); class C { static void M(D d) { } static void M(E e) { } static int i = 0; static void M() { M(() => ref i); M(() => { return ref i; }); M(delegate { return ref i; }); M(() => i); M(() => { return i; }); M(delegate { return i; }); } } "; CreateCompilationWithMscorlib45(text).VerifyDiagnostics(); } [Fact] public void RefLambdaInferenceArgumentBadRefReturn() { var text = @" delegate int E(); class C { static void ME(E e) { } static int i = 0; static void M() { ME(() => ref i); ME(() => { return ref i; }); ME(delegate { return ref i; }); } } "; CreateCompilationWithMscorlib45(text).VerifyDiagnostics( // (11,22): error CS8149: By-reference returns may only be used in by-reference returning methods. // ME(() => ref i); Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "i").WithLocation(11, 22), // (12,20): error CS8149: By-reference returns may only be used in by-reference returning methods. // ME(() => { return ref i; }); Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "return").WithLocation(12, 20), // (13,23): error CS8149: By-reference returns may only be used in by-reference returning methods. // ME(delegate { return ref i; }); Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "return").WithLocation(13, 23)); } [Fact] public void RefLambdaInferenceDelegateCreationBadRefReturn() { var text = @" delegate int E(); class C { static int i = 0; static void M() { var e = new E(() => ref i); e = new E(() => { return ref i; }); e = new E(delegate { return ref i; }); } } "; CreateCompilationWithMscorlib45(text).VerifyDiagnostics( // (9,33): error CS8149: By-reference returns may only be used in by-reference returning methods. // var e = new E(() => ref i); Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "i").WithLocation(9, 33), // (10,27): error CS8149: By-reference returns may only be used in by-reference returning methods. // e = new E(() => { return ref i; }); Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "return").WithLocation(10, 27), // (11,30): error CS8149: By-reference returns may only be used in by-reference returning methods. // e = new E(delegate { return ref i; }); Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "return").WithLocation(11, 30)); } [Fact] public void RefLambdaInferenceMixedByValueAndByRefReturns() { var text = @" delegate ref int D(); delegate int E(); class C { static void MD(D e) { } static void ME(E e) { } static int i = 0; static void M() { MD(() => { if (i == 0) { return ref i; } return i; }); ME(() => { if (i == 0) { return ref i; } return i; }); } } "; CreateCompilationWithMscorlib45(text).VerifyDiagnostics( // (18,13): error CS8150: By-value returns may only be used in by-value returning methods. // return i; Diagnostic(ErrorCode.ERR_MustHaveRefReturn, "return").WithLocation(18, 13), // (23,17): error CS8149: By-reference returns may only be used in by-reference returning methods. // return ref i; Diagnostic(ErrorCode.ERR_MustNotHaveRefReturn, "return").WithLocation(23, 17)); } [WorkItem(1112875, "DevDiv")] [WorkItem(1112875, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1112875")] [Fact] public void Bug1112875_1() { var comp = CreateCompilation(@" using System; class Program { static void Main() { ICloneable c = """"; Goo(() => (c.Clone()), null); } static void Goo(Action x, string y) { } static void Goo(Func x, object y) { Console.WriteLine(42); } }", options: TestOptions.ReleaseExe); comp.VerifyDiagnostics(); CompileAndVerify(comp, expectedOutput: "42"); } [WorkItem(1112875, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1112875")] [Fact] public void Bug1112875_2() { var comp = CreateCompilation(@" class Program { void M() { var d = new System.Action(() => (new object())); } } "); comp.VerifyDiagnostics( // (6,41): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement // var d = new System.Action(() => (new object())); Diagnostic(ErrorCode.ERR_IllegalStatement, "(new object())").WithLocation(6, 41)); } [WorkItem(1830, "https://github.com/dotnet/roslyn/issues/1830")] [Fact] public void FuncOfVoid() { var comp = CreateCompilation(@" using System; class Program { void M1(Func f) {} void Main(string[] args) { M1(() => { return System.Console.Beep(); }); } } "); comp.VerifyDiagnostics( // (8,27): error CS4029: Cannot return an expression of type 'void' // M1(() => { return System.Console.Beep(); }); Diagnostic(ErrorCode.ERR_CantReturnVoid, "System.Console.Beep()").WithLocation(8, 27) ); } [Fact, WorkItem(1179899, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1179899")] public void ParameterReference_01() { var src = @" using System; class Program { static Func stuff() { return a => a. } } "; var compilation = CreateCompilation(src); compilation.VerifyDiagnostics( // (8,23): error CS1001: Identifier expected // return a => a. Diagnostic(ErrorCode.ERR_IdentifierExpected, "").WithLocation(8, 23), // (8,23): error CS1002: ; expected // return a => a. Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(8, 23) ); var tree = compilation.SyntaxTrees.Single(); var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); Assert.Equal("a.", node.Parent.ToString().Trim()); var semanticModel = compilation.GetSemanticModel(tree); var symbolInfo = semanticModel.GetSymbolInfo(node); Assert.Equal("Program a", symbolInfo.Symbol.ToTestDisplayString()); } [Fact, WorkItem(1179899, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1179899")] public void ParameterReference_02() { var src = @" using System; class Program { static void stuff() { Func l = a => a. } } "; var compilation = CreateCompilation(src); compilation.VerifyDiagnostics( // (8,42): error CS1001: Identifier expected // Func l = a => a. Diagnostic(ErrorCode.ERR_IdentifierExpected, "").WithLocation(8, 42), // (8,42): error CS1002: ; expected // Func l = a => a. Diagnostic(ErrorCode.ERR_SemicolonExpected, "").WithLocation(8, 42) ); var tree = compilation.SyntaxTrees.Single(); var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); Assert.Equal("a.", node.Parent.ToString().Trim()); var semanticModel = compilation.GetSemanticModel(tree); var symbolInfo = semanticModel.GetSymbolInfo(node); Assert.Equal("Program a", symbolInfo.Symbol.ToTestDisplayString()); } [Fact, WorkItem(1179899, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1179899")] public void ParameterReference_03() { var src = @" using System; class Program { static void stuff() { M1(a => a.); } static void M1(Func l){} } "; var compilation = CreateCompilation(src); compilation.VerifyDiagnostics( // (8,20): error CS1001: Identifier expected // M1(a => a.); Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(8, 20) ); var tree = compilation.SyntaxTrees.Single(); var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); Assert.Equal("a.", node.Parent.ToString().Trim()); var semanticModel = compilation.GetSemanticModel(tree); var symbolInfo = semanticModel.GetSymbolInfo(node); Assert.Equal("Program a", symbolInfo.Symbol.ToTestDisplayString()); } [Fact, WorkItem(1179899, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1179899")] public void ParameterReference_04() { var src = @" using System; class Program { static void stuff() { var l = (Func) (a => a.); } } "; var compilation = CreateCompilation(src); compilation.VerifyDiagnostics( // (8,49): error CS1001: Identifier expected // var l = (Func) (a => a.); Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(8, 49) ); var tree = compilation.SyntaxTrees.Single(); var node = tree.GetRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "a").Single(); Assert.Equal("a.", node.Parent.ToString().Trim()); var semanticModel = compilation.GetSemanticModel(tree); var symbolInfo = semanticModel.GetSymbolInfo(node); Assert.Equal("Program a", symbolInfo.Symbol.ToTestDisplayString()); } [Fact] [WorkItem(3826, "https://github.com/dotnet/roslyn/issues/3826")] public void ExpressionTreeSelfAssignmentShouldError() { var source = @" using System; using System.Linq.Expressions; class Program { static void Main() { Expression> x = y => y = y; } }"; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); compilation.VerifyDiagnostics( // (9,45): warning CS1717: Assignment made to same variable; did you mean to assign something else? // Expression> x = y => y = y; Diagnostic(ErrorCode.WRN_AssignmentToSelf, "y = y").WithLocation(9, 45), // (9,45): error CS0832: An expression tree may not contain an assignment operator // Expression> x = y => y = y; Diagnostic(ErrorCode.ERR_ExpressionTreeContainsAssignment, "y = y").WithLocation(9, 45)); } [Fact, WorkItem(30776, "https://github.com/dotnet/roslyn/issues/30776")] public void RefStructExpressionTree() { var text = @" using System; using System.Linq.Expressions; public class Class1 { public void Method1() { Method((Class1 c) => c.Method2(default(Struct1))); } public void Method2(Struct1 s1) { } public static void Method(Expression> expression) { } } public ref struct Struct1 { } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics( // (8,40): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'Struct1'. // Method((Class1 c) => c.Method2(default(Struct1))); Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "default(Struct1)").WithArguments("Struct1").WithLocation(8, 40)); } [Fact, WorkItem(30776, "https://github.com/dotnet/roslyn/issues/30776")] public void RefStructDefaultExpressionTree() { var text = @" using System; using System.Linq.Expressions; public class Class1 { public void Method1() { Method((Class1 c) => c.Method2(default)); } public void Method2(Struct1 s1) { } public static void Method(Expression> expression) { } } public ref struct Struct1 { } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics( // (8,40): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'Struct1'. // Method((Class1 c) => c.Method2(default)); Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "default").WithArguments("Struct1").WithLocation(8, 40)); } [Fact, WorkItem(30776, "https://github.com/dotnet/roslyn/issues/30776")] public void RefStructDefaultCastExpressionTree() { var text = @" using System; using System.Linq.Expressions; public class Class1 { public void Method1() { Method((Class1 c) => c.Method2((Struct1) default)); } public void Method2(Struct1 s1) { } public static void Method(Expression> expression) { } } public ref struct Struct1 { } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics( // (8,50): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'Struct1'. // Method((Class1 c) => c.Method2((Struct1) default)); Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "default").WithArguments("Struct1").WithLocation(8, 50)); } [Fact, WorkItem(30776, "https://github.com/dotnet/roslyn/issues/30776")] public void RefStructNewExpressionTree() { var text = @" using System; using System.Linq.Expressions; public class Class1 { public void Method1() { Method((Class1 c) => c.Method2(new Struct1())); } public void Method2(Struct1 s1) { } public static void Method(Expression> expression) { } } public ref struct Struct1 { } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics( // (8,40): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'Struct1'. // Method((Class1 c) => c.Method2(new Struct1())); Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "new Struct1()").WithArguments("Struct1").WithLocation(8, 40)); } [Fact, WorkItem(30776, "https://github.com/dotnet/roslyn/issues/30776")] public void RefStructParamExpressionTree() { var text = @" using System.Linq.Expressions; public delegate void Delegate1(Struct1 s); public class Class1 { public void Method1() { Method((Struct1 s) => Method2()); } public void Method2() { } public static void Method(Expression expression) { } } public ref struct Struct1 { } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics( // (9,25): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'Struct1'. // Method((Struct1 s) => Method2()); Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "s").WithArguments("Struct1").WithLocation(9, 25)); } [Fact, WorkItem(30776, "https://github.com/dotnet/roslyn/issues/30776")] public void RefStructParamLambda() { var text = @" public delegate void Delegate1(Struct1 s); public class Class1 { public void Method1() { Method((Struct1 s) => Method2()); } public void Method2() { } public static void Method(Delegate1 expression) { } } public ref struct Struct1 { } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics(); } [Fact, WorkItem(30776, "https://github.com/dotnet/roslyn/issues/30776")] public void TypedReferenceExpressionTree() { var text = @" using System; using System.Linq.Expressions; public class Class1 { public void Method1() { Method(() => Method2(default)); } public void Method2(TypedReference tr) { } public static void Method(Expression expression) { } } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics( // (8,30): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'TypedReference'. // Method(() => Method2(default)); Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "default").WithArguments("TypedReference").WithLocation(8, 30)); } [Fact, WorkItem(30776, "https://github.com/dotnet/roslyn/issues/30776")] public void TypedReferenceParamExpressionTree() { var text = @" using System; using System.Linq.Expressions; public delegate void Delegate1(TypedReference tr); public class Class1 { public void Method1() { Method((TypedReference tr) => Method2()); } public void Method2() { } public static void Method(Expression expression) { } } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(text).VerifyDiagnostics( // (9,32): error CS8640: Expression tree cannot contain value of ref struct or restricted type 'TypedReference'. // Method((TypedReference tr) => Method2()); Diagnostic(ErrorCode.ERR_ExpressionTreeCantContainRefStruct, "tr").WithArguments("TypedReference").WithLocation(9, 32)); } [Fact, WorkItem(5363, "https://github.com/dotnet/roslyn/issues/5363")] public void ReturnInferenceCache_Dynamic_vs_Object_01() { var source = @" using System; using System.Collections; using System.Collections.Generic; public static class Program { public static void Main(string[] args) { IEnumerable dynX = null; // CS1061 'object' does not contain a definition for 'Text'... // tooltip on 'var' shows IColumn instead of IEnumerable var result = dynX.Select(_ => _.Text); } public static IColumn Select(this IColumn source, Func selector) { throw new NotImplementedException(); } public static IEnumerable Select(this IEnumerable source, Func selector) { System.Console.WriteLine(""Select""); return null; } } public interface IColumn { } "; var compilation = CreateCompilation(source, new[] { CSharpRef }, options: TestOptions.ReleaseExe); CompileAndVerify(compilation, expectedOutput: "Select"); } [Fact, WorkItem(5363, "https://github.com/dotnet/roslyn/issues/5363")] public void ReturnInferenceCache_Dynamic_vs_Object_02() { var source = @" using System; using System.Collections; using System.Collections.Generic; public static class Program { public static void Main(string[] args) { IEnumerable dynX = null; // CS1061 'object' does not contain a definition for 'Text'... // tooltip on 'var' shows IColumn instead of IEnumerable var result = dynX.Select(_ => _.Text); } public static IEnumerable Select(this IEnumerable source, Func selector) { System.Console.WriteLine(""Select""); return null; } public static IColumn Select(this IColumn source, Func selector) { throw new NotImplementedException(); } } public interface IColumn { } "; var compilation = CreateCompilation(source, new[] { CSharpRef }, options: TestOptions.ReleaseExe); CompileAndVerify(compilation, expectedOutput: "Select"); } [Fact, WorkItem(1867, "https://github.com/dotnet/roslyn/issues/1867")] public void SyntaxAndSemanticErrorInLambda() { var source = @" using System; class C { public static void Main(string[] args) { Action a = () => { new X().ToString() }; a(); } } "; CreateCompilation(source).VerifyDiagnostics( // (7,47): error CS1002: ; expected // Action a = () => { new X().ToString() }; Diagnostic(ErrorCode.ERR_SemicolonExpected, "}").WithLocation(7, 47), // (7,32): error CS0246: The type or namespace name 'X' could not be found (are you missing a using directive or an assembly reference?) // Action a = () => { new X().ToString() }; Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "X").WithArguments("X").WithLocation(7, 32) ); } [Fact, WorkItem(4527, "https://github.com/dotnet/roslyn/issues/4527")] public void AnonymousMethodExpressionWithoutParameterList() { var source = @" using System; using System.Threading.Tasks; namespace RoslynAsyncDelegate { class Program { static EventHandler MyEvent; static void Main(string[] args) { MyEvent += async delegate { await Task.Delay(0); }; } } } "; var compilation = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugExe); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var node1 = tree.GetRoot().DescendantNodes().Where(n => n.IsKind(SyntaxKind.AnonymousMethodExpression)).Single(); Assert.Equal("async delegate { await Task.Delay(0); }", node1.ToString()); Assert.Equal("void System.EventHandler.Invoke(System.Object sender, System.EventArgs e)", model.GetTypeInfo(node1).ConvertedType.GetMembers("Invoke").Single().ToTestDisplayString()); var lambdaParameters = ((MethodSymbol)(model.GetSymbolInfo(node1)).Symbol).Parameters; Assert.Equal("System.Object ", lambdaParameters[0].ToTestDisplayString()); Assert.Equal("System.EventArgs ", lambdaParameters[1].ToTestDisplayString()); CompileAndVerify(compilation); } [Fact] [WorkItem(1867, "https://github.com/dotnet/roslyn/issues/1867")] public void TestLambdaWithError01() { var source = @"using System.Linq; class C { C() { string.Empty.Select(() => { new Unbound1 }); } }"; CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics( // (2,58): error CS1526: A new expression requires (), [], or {} after type // class C { C() { string.Empty.Select(() => { new Unbound1 }); } } Diagnostic(ErrorCode.ERR_BadNewExpr, "}").WithLocation(2, 58), // (2,58): error CS1002: ; expected // class C { C() { string.Empty.Select(() => { new Unbound1 }); } } Diagnostic(ErrorCode.ERR_SemicolonExpected, "}").WithLocation(2, 58), // (2,49): error CS0246: The type or namespace name 'Unbound1' could not be found (are you missing a using directive or an assembly reference?) // class C { C() { string.Empty.Select(() => { new Unbound1 }); } } Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Unbound1").WithArguments("Unbound1").WithLocation(2, 49) ); } [Fact] [WorkItem(1867, "https://github.com/dotnet/roslyn/issues/1867")] public void TestLambdaWithError02() { var source = @"using System.Linq; class C { C() { string.Empty.Select(() => { new Unbound1 ( ) }); } }"; CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics( // (2,62): error CS1002: ; expected // class C { C() { string.Empty.Select(() => { new Unbound1 ( ) }); } } Diagnostic(ErrorCode.ERR_SemicolonExpected, "}").WithLocation(2, 62), // (2,49): error CS0246: The type or namespace name 'Unbound1' could not be found (are you missing a using directive or an assembly reference?) // class C { C() { string.Empty.Select(() => { new Unbound1 ( ) }); } } Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "Unbound1").WithArguments("Unbound1").WithLocation(2, 49) ); } [Fact] [WorkItem(1867, "https://github.com/dotnet/roslyn/issues/1867")] public void TestLambdaWithError03() { var source = @"using System.Linq; class C { C() { string.Empty.Select(x => Unbound1, Unbound2 Unbound2); } }"; CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics( // (2,61): error CS1003: Syntax error, ',' expected // class C { C() { string.Empty.Select(x => Unbound1, Unbound2 Unbound2); } } Diagnostic(ErrorCode.ERR_SyntaxError, "Unbound2").WithArguments(",", "").WithLocation(2, 61), // (2,52): error CS0103: The name 'Unbound2' does not exist in the current context // class C { C() { string.Empty.Select(x => Unbound1, Unbound2 Unbound2); } } Diagnostic(ErrorCode.ERR_NameNotInContext, "Unbound2").WithArguments("Unbound2").WithLocation(2, 52), // (2,61): error CS0103: The name 'Unbound2' does not exist in the current context // class C { C() { string.Empty.Select(x => Unbound1, Unbound2 Unbound2); } } Diagnostic(ErrorCode.ERR_NameNotInContext, "Unbound2").WithArguments("Unbound2").WithLocation(2, 61), // (2,42): error CS0103: The name 'Unbound1' does not exist in the current context // class C { C() { string.Empty.Select(x => Unbound1, Unbound2 Unbound2); } } Diagnostic(ErrorCode.ERR_NameNotInContext, "Unbound1").WithArguments("Unbound1").WithLocation(2, 42) ); } [Fact] [WorkItem(1867, "https://github.com/dotnet/roslyn/issues/1867")] public void TestLambdaWithError04() { var source = @"using System.Linq; class C { C() { string.Empty.Select(x => Unbound1, Unbound2); } }"; CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics( // (2,52): error CS0103: The name 'Unbound2' does not exist in the current context // class C { C() { string.Empty.Select(x => Unbound1, Unbound2); } } Diagnostic(ErrorCode.ERR_NameNotInContext, "Unbound2").WithArguments("Unbound2").WithLocation(2, 52), // (2,42): error CS0103: The name 'Unbound1' does not exist in the current context // class C { C() { string.Empty.Select(x => Unbound1, Unbound2); } } Diagnostic(ErrorCode.ERR_NameNotInContext, "Unbound1").WithArguments("Unbound1").WithLocation(2, 42) ); } [Fact] [WorkItem(1867, "https://github.com/dotnet/roslyn/issues/1867")] public void TestLambdaWithError05() { var source = @"using System.Linq; class C { C() { Unbound2.Select(x => Unbound1); } }"; CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics( // (2,17): error CS0103: The name 'Unbound2' does not exist in the current context // class C { C() { Unbound2.Select(x => Unbound1); } } Diagnostic(ErrorCode.ERR_NameNotInContext, "Unbound2").WithArguments("Unbound2").WithLocation(2, 17), // (2,38): error CS0103: The name 'Unbound1' does not exist in the current context // class C { C() { Unbound2.Select(x => Unbound1); } } Diagnostic(ErrorCode.ERR_NameNotInContext, "Unbound1").WithArguments("Unbound1").WithLocation(2, 38) ); } [Fact] [WorkItem(4480, "https://github.com/dotnet/roslyn/issues/4480")] public void TestLambdaWithError06() { var source = @"class Program { static void Main(string[] args) { // completion should work even in a syntactically invalid lambda var handler = new MyDelegateType((s, e) => { e. }); } } public delegate void MyDelegateType( object sender, MyArgumentType e ); public class MyArgumentType { public int SomePublicMember; }"; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source) .VerifyDiagnostics( // var handler = new MyDelegateType((s, e) => { e. }); Diagnostic(ErrorCode.ERR_IdentifierExpected, "}").WithLocation(6, 57), // (6,57): error CS1002: ; expected // var handler = new MyDelegateType((s, e) => { e. }); Diagnostic(ErrorCode.ERR_SemicolonExpected, "}").WithLocation(6, 57) ); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); var lambda = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single(); var eReference = lambda.Body.DescendantNodes().OfType().First(); Assert.Equal("e", eReference.ToString()); var typeInfo = sm.GetTypeInfo(eReference); Assert.Equal("MyArgumentType", typeInfo.Type.Name); Assert.Equal(TypeKind.Class, typeInfo.Type.TypeKind); Assert.NotEmpty(typeInfo.Type.GetMembers("SomePublicMember")); } [Fact] [WorkItem(11053, "https://github.com/dotnet/roslyn/issues/11053")] [WorkItem(11358, "https://github.com/dotnet/roslyn/issues/11358")] public void TestLambdaWithError07() { var source = @"using System; using System.Collections.Generic; public static class Program { public static void Main() { var parameter = new List(); var result = parameter.FirstOrDefault(x => x. ); } } public static class Enumerable { public static TSource FirstOrDefault(this IEnumerable source, TSource defaultValue) { return default(TSource); } public static TSource FirstOrDefault(this IEnumerable source, Func predicate, TSource defaultValue) { return default(TSource); } }"; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics( // (9,55): error CS1001: Identifier expected // var result = parameter.FirstOrDefault(x => x. ); Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(9, 55) ); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); var lambda = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single(); var eReference = lambda.Body.DescendantNodes().OfType().First(); Assert.Equal("x", eReference.ToString()); var typeInfo = sm.GetTypeInfo(eReference); Assert.Equal(TypeKind.Class, typeInfo.Type.TypeKind); Assert.Equal("String", typeInfo.Type.Name); Assert.NotEmpty(typeInfo.Type.GetMembers("Replace")); } [Fact] [WorkItem(11053, "https://github.com/dotnet/roslyn/issues/11053")] [WorkItem(11358, "https://github.com/dotnet/roslyn/issues/11358")] public void TestLambdaWithError08() { var source = @"using System; using System.Collections.Generic; public static class Program { public static void Main() { var parameter = new List(); var result = parameter.FirstOrDefault(x => x. ); } } public static class Enumerable { public static TSource FirstOrDefault(this IEnumerable source, params TSource[] defaultValue) { return default(TSource); } public static TSource FirstOrDefault(this IEnumerable source, Func predicate, params TSource[] defaultValue) { return default(TSource); } }"; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics( // (9,55): error CS1001: Identifier expected // var result = parameter.FirstOrDefault(x => x. ); Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(9, 55) ); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); var lambda = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single(); var eReference = lambda.Body.DescendantNodes().OfType().First(); Assert.Equal("x", eReference.ToString()); var typeInfo = sm.GetTypeInfo(eReference); Assert.Equal(TypeKind.Class, typeInfo.Type.TypeKind); Assert.Equal("String", typeInfo.Type.Name); Assert.NotEmpty(typeInfo.Type.GetMembers("Replace")); } [Fact] [WorkItem(11053, "https://github.com/dotnet/roslyn/issues/11053")] [WorkItem(11358, "https://github.com/dotnet/roslyn/issues/11358")] public void TestLambdaWithError09() { var source = @"using System; public static class Program { public static void Main() { var parameter = new MyList(); var result = parameter.FirstOrDefault(x => x. ); } } public class MyList { public TSource FirstOrDefault(TSource defaultValue) { return default(TSource); } public TSource FirstOrDefault(Func predicate, TSource defaultValue) { return default(TSource); } } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics( // (8,55): error CS1001: Identifier expected // var result = parameter.FirstOrDefault(x => x. ); Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(8, 55) ); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); var lambda = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single(); var eReference = lambda.Body.DescendantNodes().OfType().First(); Assert.Equal("x", eReference.ToString()); var typeInfo = sm.GetTypeInfo(eReference); Assert.Equal(TypeKind.Class, typeInfo.Type.TypeKind); Assert.Equal("String", typeInfo.Type.Name); Assert.NotEmpty(typeInfo.Type.GetMembers("Replace")); } [Fact] [WorkItem(11053, "https://github.com/dotnet/roslyn/issues/11053")] [WorkItem(11358, "https://github.com/dotnet/roslyn/issues/11358")] public void TestLambdaWithError10() { var source = @"using System; public static class Program { public static void Main() { var parameter = new MyList(); var result = parameter.FirstOrDefault(x => x. ); } } public class MyList { public TSource FirstOrDefault(params TSource[] defaultValue) { return default(TSource); } public TSource FirstOrDefault(Func predicate, params TSource[] defaultValue) { return default(TSource); } } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics( // (8,55): error CS1001: Identifier expected // var result = parameter.FirstOrDefault(x => x. ); Diagnostic(ErrorCode.ERR_IdentifierExpected, ")").WithLocation(8, 55) ); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); var lambda = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single(); var eReference = lambda.Body.DescendantNodes().OfType().First(); Assert.Equal("x", eReference.ToString()); var typeInfo = sm.GetTypeInfo(eReference); Assert.Equal(TypeKind.Class, typeInfo.Type.TypeKind); Assert.Equal("String", typeInfo.Type.Name); Assert.NotEmpty(typeInfo.Type.GetMembers("Replace")); } [Fact] [WorkItem(557, "https://github.com/dotnet/roslyn/issues/557")] public void TestLambdaWithError11() { var source = @"using System.Linq; public static class Program { public static void Main() { var x = new { X = """".Select(c => c. Y = 0, }; } } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); var lambda = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single(); var eReference = lambda.Body.DescendantNodes().OfType().First(); Assert.Equal("c", eReference.ToString()); var typeInfo = sm.GetTypeInfo(eReference); Assert.Equal(TypeKind.Struct, typeInfo.Type.TypeKind); Assert.Equal("Char", typeInfo.Type.Name); Assert.NotEmpty(typeInfo.Type.GetMembers("IsHighSurrogate")); // check it is the char we know and love } [Fact] [WorkItem(5498, "https://github.com/dotnet/roslyn/issues/5498")] public void TestLambdaWithError12() { var source = @"using System.Linq; class Program { static void Main(string[] args) { var z = args.Select(a => a. var goo = } }"; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); var lambda = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single(); var eReference = lambda.Body.DescendantNodes().OfType().First(); Assert.Equal("a", eReference.ToString()); var typeInfo = sm.GetTypeInfo(eReference); Assert.Equal(TypeKind.Class, typeInfo.Type.TypeKind); Assert.Equal("String", typeInfo.Type.Name); Assert.NotEmpty(typeInfo.Type.GetMembers("Replace")); } [WorkItem(5498, "https://github.com/dotnet/roslyn/issues/5498")] [WorkItem(11358, "https://github.com/dotnet/roslyn/issues/11358")] [Fact] public void TestLambdaWithError13() { // These tests ensure we attempt to perform type inference and bind a lambda expression // argument even when there are too many or too few arguments to an invocation, in the // case when there is more than one method in the method group. // See https://github.com/dotnet/roslyn/issues/11901 for the case of one method in the group var source = @"using System; class Program { static void Main(string[] args) { Thing t = null; t.X1(x => x, 1); // too many args t.X2(x => x); // too few args t.M2(string.Empty, x => x, 1); // too many args t.M3(string.Empty, x => x); // too few args } } public class Thing { public void M2(T x, Func func) {} public void M3(T x, Func func, T y) {} // Ensure we have more than one method in the method group public void M2() {} public void M3() {} } public static class XThing { public static Thing X1(this Thing self, Func func) => null; public static Thing X2(this Thing self, Func func, int i) => null; // Ensure we have more than one method in the method group public static void X1(this object self) {} public static void X2(this object self) {} } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); foreach (var lambda in tree.GetRoot().DescendantNodes().OfType()) { var reference = lambda.Body.DescendantNodesAndSelf().OfType().First(); Assert.Equal("x", reference.ToString()); var typeInfo = sm.GetTypeInfo(reference); Assert.Equal(TypeKind.Class, typeInfo.Type.TypeKind); Assert.Equal("String", typeInfo.Type.Name); Assert.NotEmpty(typeInfo.Type.GetMembers("Replace")); } } [Fact] [WorkItem(11901, "https://github.com/dotnet/roslyn/issues/11901")] public void TestLambdaWithError15() { // These tests ensure we attempt to perform type inference and bind a lambda expression // argument even when there are too many or too few arguments to an invocation, in the // case when there is exactly one method in the method group. var source = @"using System; class Program { static void Main(string[] args) { Thing t = null; t.X1(x => x, 1); // too many args t.X2(x => x); // too few args t.M2(string.Empty, x => x, 1); // too many args t.M3(string.Empty, x => x); // too few args } } public class Thing { public void M2(T x, Func func) {} public void M3(T x, Func func, T y) {} } public static class XThing { public static Thing X1(this Thing self, Func func) => null; public static Thing X2(this Thing self, Func func, int i) => null; } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); foreach (var lambda in tree.GetRoot().DescendantNodes().OfType()) { var reference = lambda.Body.DescendantNodesAndSelf().OfType().First(); Assert.Equal("x", reference.ToString()); var typeInfo = sm.GetTypeInfo(reference); Assert.Equal(TypeKind.Class, typeInfo.Type.TypeKind); Assert.Equal("String", typeInfo.Type.Name); Assert.NotEmpty(typeInfo.Type.GetMembers("Replace")); } } [Fact] [WorkItem(11901, "https://github.com/dotnet/roslyn/issues/11901")] public void TestLambdaWithError16() { // These tests ensure we use the substituted method to bind a lambda expression // argument even when there are too many or too few arguments to an invocation, in the // case when there is exactly one method in the method group. var source = @"using System; class Program { static void Main(string[] args) { Thing t = null; t.X1(x => x, 1); // too many args t.X2(x => x); // too few args t.M2(string.Empty, x => x, 1); // too many args t.M3(string.Empty, x => x); // too few args } } public class Thing { public void M2(T x, Func func) {} public void M3(T x, Func func, T y) {} } public static class XThing { public static Thing X1(this Thing self, Func func) => null; public static Thing X2(this Thing self, Func func, int i) => null; } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); foreach (var lambda in tree.GetRoot().DescendantNodes().OfType()) { var reference = lambda.Body.DescendantNodesAndSelf().OfType().First(); Assert.Equal("x", reference.ToString()); var typeInfo = sm.GetTypeInfo(reference); Assert.Equal(TypeKind.Class, typeInfo.Type.TypeKind); Assert.Equal("String", typeInfo.Type.Name); Assert.NotEmpty(typeInfo.Type.GetMembers("Replace")); } } [Fact] [WorkItem(12063, "https://github.com/dotnet/roslyn/issues/12063")] public void TestLambdaWithError17() { var source = @"using System; class Program { static void Main(string[] args) { Ma(action: (x, y) => x.ToString(), t: string.Empty); Mb(action: (x, y) => x.ToString(), t: string.Empty); } static void Ma(T t, Action action) { } static void Mb(T t, Action action) { } static void Mb() { } } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); foreach (var lambda in tree.GetRoot().DescendantNodes().OfType()) { var reference = lambda.Body.DescendantNodesAndSelf().OfType().First(); Assert.Equal("x", reference.ToString()); var typeInfo = sm.GetTypeInfo(reference); Assert.Equal(TypeKind.Class, typeInfo.Type.TypeKind); Assert.Equal("String", typeInfo.Type.Name); Assert.NotEmpty(typeInfo.Type.GetMembers("Replace")); } } [Fact] [WorkItem(12063, "https://github.com/dotnet/roslyn/issues/12063")] public void TestLambdaWithError18() { var source = @"using System; class Program { static void Main(string[] args) { Ma(string.Empty, (x, y) => x.ToString()); Mb(string.Empty, (x, y) => x.ToString()); } static void Ma(T t, Action action) { } static void Mb(T t, Action action) { } static void Mb() { } } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); foreach (var lambda in tree.GetRoot().DescendantNodes().OfType()) { var reference = lambda.Body.DescendantNodesAndSelf().OfType().First(); Assert.Equal("x", reference.ToString()); var typeInfo = sm.GetTypeInfo(reference); Assert.Equal(TypeKind.Class, typeInfo.Type.TypeKind); Assert.Equal("String", typeInfo.Type.Name); Assert.NotEmpty(typeInfo.Type.GetMembers("Replace")); } } [Fact] [WorkItem(12063, "https://github.com/dotnet/roslyn/issues/12063")] public void TestLambdaWithError19() { var source = @"using System; using System.Linq.Expressions; class Program { static void Main(string[] args) { Ma(string.Empty, (x, y) => x.ToString()); Mb(string.Empty, (x, y) => x.ToString()); Mc(string.Empty, (x, y) => x.ToString()); } static void Ma(T t, Expression> action) { } static void Mb(T t, Expression> action) { } static void Mb(T t, Action action) { } static void Mc(T t, Expression> action) { } static void Mc() { } } "; var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); foreach (var lambda in tree.GetRoot().DescendantNodes().OfType()) { var reference = lambda.Body.DescendantNodesAndSelf().OfType().First(); Assert.Equal("x", reference.ToString()); var typeInfo = sm.GetTypeInfo(reference); Assert.Equal(TypeKind.Class, typeInfo.Type.TypeKind); Assert.Equal("String", typeInfo.Type.Name); Assert.NotEmpty(typeInfo.Type.GetMembers("Replace")); } } // See MaxParameterListsForErrorRecovery. [Fact] public void BuildArgumentsForErrorRecovery_ManyOverloads() { BuildArgumentsForErrorRecovery_ManyOverloads_Internal(Binder.MaxParameterListsForErrorRecovery - 1, tooMany: false); BuildArgumentsForErrorRecovery_ManyOverloads_Internal(Binder.MaxParameterListsForErrorRecovery, tooMany: true); } private void BuildArgumentsForErrorRecovery_ManyOverloads_Internal(int n, bool tooMany) { var builder = new StringBuilder(); builder.AppendLine("using System;"); for (int i = 0; i < n; i++) { builder.AppendLine($"class C{i} {{ }}"); } builder.Append( @"class A { } class B { } class C { void M() { F(1, (t, a, b, c) => { }); var o = this[(a, b, c) => { }]; } "); // Too few parameters. AppendLines(builder, n, i => $" void F(T t, Action a) {{ }}"); AppendLines(builder, n, i => $" object this[Action a] => {i}"); // Type inference failure. AppendLines(builder, n, i => $" void F(T t, Action a) where U : T {{ }}"); // Too many parameters. AppendLines(builder, n, i => $" void F(T t, Action a) {{ }}"); AppendLines(builder, n, i => $" object this[Action a] => {i}"); builder.AppendLine("}"); var source = builder.ToString(); var compilation = CreateCompilationWithMscorlib40AndSystemCore(source); var tree = compilation.SyntaxTrees[0]; var sm = compilation.GetSemanticModel(tree); var lambdas = tree.GetRoot().DescendantNodes().OfType().ToArray(); // F(1, (t, a, b, c) => { }); var lambda = lambdas[0]; var parameters = lambda.ParameterList.Parameters; var parameter = (ParameterSymbol)sm.GetDeclaredSymbol(parameters[0]); Assert.False(parameter.Type.TypeSymbol.IsErrorType()); Assert.Equal("System.Int32 t", parameter.ToTestDisplayString()); parameter = (ParameterSymbol)sm.GetDeclaredSymbol(parameters[1]); Assert.False(parameter.Type.TypeSymbol.IsErrorType()); Assert.Equal("A a", parameter.ToTestDisplayString()); parameter = (ParameterSymbol)sm.GetDeclaredSymbol(parameters[3]); Assert.Equal(tooMany, parameter.Type.TypeSymbol.IsErrorType()); Assert.Equal(tooMany ? "? c" : "C c", parameter.ToTestDisplayString()); // var o = this[(a, b, c) => { }]; lambda = lambdas[1]; parameters = lambda.ParameterList.Parameters; parameter = (ParameterSymbol)sm.GetDeclaredSymbol(parameters[0]); Assert.False(parameter.Type.TypeSymbol.IsErrorType()); Assert.Equal("A a", parameter.ToTestDisplayString()); parameter = (ParameterSymbol)sm.GetDeclaredSymbol(parameters[2]); Assert.Equal(tooMany, parameter.Type.TypeSymbol.IsErrorType()); Assert.Equal(tooMany ? "? c" : "C c", parameter.ToTestDisplayString()); } private static void AppendLines(StringBuilder builder, int n, Func getLine) { for (int i = 0; i < n; i++) { builder.AppendLine(getLine(i)); } } [Fact] [WorkItem(13797, "https://github.com/dotnet/roslyn/issues/13797")] public void DelegateAsAction() { var source = @" using System; public static class C { public static void M() => Dispatch(delegate { }); public static T Dispatch(Func func) => default(T); public static void Dispatch(Action func) { } }"; var comp = CreateCompilation(source); CompileAndVerify(comp); } [Fact, WorkItem(278481, "https://devdiv.visualstudio.com/DevDiv/_workitems?id=278481")] public void LambdaReturningNull_1() { var src = @" public static class ExtensionMethods { public static System.Linq.IQueryable LeftOuterJoin( this System.Linq.IQueryable outerValues, System.Linq.IQueryable innerValues, System.Linq.Expressions.Expression> outerKeySelector, System.Linq.Expressions.Expression> innerKeySelector, System.Linq.Expressions.Expression> fullResultSelector, System.Linq.Expressions.Expression> partialResultSelector, System.Collections.Generic.IEqualityComparer comparer) { return null; } public static System.Linq.IQueryable LeftOuterJoin( this System.Linq.IQueryable outerValues, System.Linq.IQueryable innerValues, System.Linq.Expressions.Expression> outerKeySelector, System.Linq.Expressions.Expression> innerKeySelector, System.Linq.Expressions.Expression> fullResultSelector, System.Linq.Expressions.Expression> partialResultSelector) { System.Console.WriteLine(""1""); return null; } public static System.Collections.Generic.IEnumerable LeftOuterJoin( this System.Collections.Generic.IEnumerable outerValues, System.Linq.IQueryable innerValues, System.Func outerKeySelector, System.Func innerKeySelector, System.Func fullResultSelector, System.Func partialResultSelector) { System.Console.WriteLine(""2""); return null; } public static System.Collections.Generic.IEnumerable LeftOuterJoin( this System.Collections.Generic.IEnumerable outerQueryable, System.Collections.Generic.IEnumerable innerQueryable, System.Func outerKeySelector, System.Func innerKeySelector, System.Func resultSelector) { return null; } } partial class C { public static void Main() { System.Linq.IQueryable outerValue = null; System.Linq.IQueryable innerValues = null; outerValue.LeftOuterJoin(innerValues, co => co.id, coa => coa.id, (co, coa) => null, co => co); } } class A { public int id=2; } class B { public int id = 2; }"; var comp = CreateCompilationWithMscorlib40AndSystemCore(src, options: TestOptions.DebugExe); CompileAndVerify(comp, expectedOutput: "1"); } [Fact, WorkItem(296550, "https://devdiv.visualstudio.com/DevDiv/_workitems?id=296550")] public void LambdaReturningNull_2() { var src = @" class Test1 { public void M1(System.Func x) {} public void M1(System.Func x) {} public void M2(System.Func x) {} public void M2(System.Func x) {} } class Test2 : Test1 { void Main() { M1(()=> null); M2(()=> null); } } "; var comp = CreateCompilation(src, options: TestOptions.DebugDll); comp.VerifyDiagnostics( // (10,32): error CS1001: Identifier expected // class Test2 : Test1 Diagnostic(ErrorCode.ERR_IdentifierExpected, ">").WithLocation(10, 32) ); } [Fact, WorkItem(22662, "https://github.com/dotnet/roslyn/issues/22662")] public void LambdaSquigglesArea() { var src = @" class C { void M() { System.Func> x = x1 => x2 => { error(); }; } } "; var comp = CreateCompilation(src); comp.VerifyDiagnostics( // (8,13): error CS0103: The name 'error' does not exist in the current context // error(); Diagnostic(ErrorCode.ERR_NameNotInContext, "error").WithArguments("error").WithLocation(8, 13), // (6,58): error CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type // System.Func> x = x1 => x2 => Diagnostic(ErrorCode.ERR_CantConvAnonMethReturns, "x2 =>").WithArguments("lambda expression").WithLocation(6, 58) ); } [Fact, WorkItem(22662, "https://github.com/dotnet/roslyn/issues/22662")] public void LambdaSquigglesAreaInAsync() { var src = @" class C { void M() { System.Func>> x = async x1 => x2 => { error(); }; } } "; var comp = CreateCompilation(src); comp.VerifyDiagnostics( // (8,13): error CS0103: The name 'error' does not exist in the current context // error(); Diagnostic(ErrorCode.ERR_NameNotInContext, "error").WithArguments("error").WithLocation(8, 13), // (6,93): error CS4010: Cannot convert async lambda expression to delegate type 'Task>'. An async lambda expression may return void, Task or Task, none of which are convertible to 'Task>'. // System.Func>> x = async x1 => x2 => Diagnostic(ErrorCode.ERR_CantConvAsyncAnonFuncReturns, "x2 =>").WithArguments("lambda expression", "System.Threading.Tasks.Task>").WithLocation(6, 93), // (6,90): warning CS1998: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. // System.Func>> x = async x1 => x2 => Diagnostic(ErrorCode.WRN_AsyncLacksAwaits, "=>").WithLocation(6, 90) ); } [Fact, WorkItem(22662, "https://github.com/dotnet/roslyn/issues/22662")] public void DelegateSquigglesArea() { var src = @" class C { void M() { System.Func> x = x1 => delegate(bool x2) { error(); }; } } "; var comp = CreateCompilation(src); comp.VerifyDiagnostics( // (8,13): error CS0103: The name 'error' does not exist in the current context // error(); Diagnostic(ErrorCode.ERR_NameNotInContext, "error").WithArguments("error").WithLocation(8, 13), // (6,58): error CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type // System.Func> x = x1 => delegate(bool x2) Diagnostic(ErrorCode.ERR_CantConvAnonMethReturns, "delegate(bool x2)").WithArguments("lambda expression").WithLocation(6, 58) ); } [Fact, WorkItem(22662, "https://github.com/dotnet/roslyn/issues/22662")] public void DelegateWithoutArgumentsSquigglesArea() { var src = @" class C { void M() { System.Func x = x1 => delegate { error(); }; } } "; var comp = CreateCompilation(src); comp.VerifyDiagnostics( // (8,13): error CS0103: The name 'error' does not exist in the current context // error(); Diagnostic(ErrorCode.ERR_NameNotInContext, "error").WithArguments("error").WithLocation(8, 13), // (6,52): error CS1662: Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type // System.Func x = x1 => delegate Diagnostic(ErrorCode.ERR_CantConvAnonMethReturns, "delegate").WithArguments("lambda expression").WithLocation(6, 52) ); } [Fact] public void ThrowExpression_Lambda() { var src = @"using System; class C { public static void Main() { Action a = () => throw new Exception(""1""); try { a(); } catch (Exception ex) { Console.Write(ex.Message); } Func b = x => throw new Exception(""2""); try { b(0); } catch (Exception ex) { Console.Write(ex.Message); } b = (int x) => throw new Exception(""3""); try { b(0); } catch (Exception ex) { Console.Write(ex.Message); } b = (x) => throw new Exception(""4""); try { b(0); } catch (Exception ex) { Console.Write(ex.Message); } } }"; var comp = CreateCompilationWithMscorlib40AndSystemCore(src, options: TestOptions.DebugExe); CompileAndVerify(comp, expectedOutput: "1234"); } [Fact, WorkItem(23883, "https://github.com/dotnet/roslyn/issues/23883")] public void InMalformedEmbeddedStatement_01() { var source = @" class Program { void method1() { if (method2()) .Any(b => b.ContentType, out var chars) { } } } "; var tree = SyntaxFactory.ParseSyntaxTree(source); var comp = CreateCompilation(tree); ExpressionSyntax contentType = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "ContentType").Single(); var model = comp.GetSemanticModel(tree); Assert.Equal("ContentType", contentType.ToString()); Assert.Null(model.GetSymbolInfo(contentType).Symbol); Assert.Equal(TypeKind.Error, model.GetTypeInfo(contentType).Type.TypeKind); ExpressionSyntax b = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "b").Single(); model = comp.GetSemanticModel(tree); Assert.Equal("b", b.ToString()); ISymbol symbol = model.GetSymbolInfo(b).Symbol; Assert.Equal(SymbolKind.Parameter, symbol.Kind); Assert.Equal("? b", symbol.ToTestDisplayString()); Assert.Equal(TypeKind.Error, model.GetTypeInfo(b).Type.TypeKind); ParameterSyntax parameterSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single(); model = comp.GetSemanticModel(tree); symbol = model.GetDeclaredSymbol(parameterSyntax); Assert.Equal(SymbolKind.Parameter, symbol.Kind); Assert.Equal("? b", symbol.ToTestDisplayString()); } [Fact, WorkItem(23883, "https://github.com/dotnet/roslyn/issues/23883")] public void InMalformedEmbeddedStatement_02() { var source = @" class Program { void method1() { if (method2()) .Any(b => b.ContentType, out var chars) { } } } "; var tree = SyntaxFactory.ParseSyntaxTree(source); var comp = CreateCompilation(tree); ExpressionSyntax contentType = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "ContentType").Single(); var model = comp.GetSemanticModel(tree); Assert.Equal("ContentType", contentType.ToString()); var lambda = (MethodSymbol)model.GetEnclosingSymbol(contentType.SpanStart); Assert.Equal(MethodKind.AnonymousFunction, lambda.MethodKind); ExpressionSyntax b = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Where(id => id.Identifier.ValueText == "b").Single(); model = comp.GetSemanticModel(tree); Assert.Equal("b", b.ToString()); lambda = (MethodSymbol)model.GetEnclosingSymbol(b.SpanStart); Assert.Equal(MethodKind.AnonymousFunction, lambda.MethodKind); model = comp.GetSemanticModel(tree); ParameterSyntax parameterSyntax = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single(); Assert.Equal("void Program.method1()", model.GetEnclosingSymbol(parameterSyntax.SpanStart).ToTestDisplayString()); } [Fact] public void ShadowNames_Local() { var source = @"#pragma warning disable 0219 #pragma warning disable 8321 using System; using System.Linq; class Program { static void M() { Action a1 = () => { object x = 0; }; // local Action a2 = x => { }; // parameter Action a3 = (string x) => { }; // parameter object x = null; Action a4 = () => { void x() { } }; // method Action a5 = () => { _ = from x in new[] { 1, 2, 3 } select x; }; // range variable } }"; var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3); comp.VerifyDiagnostics( // (9,36): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // Action a1 = () => { object x = 0; }; // local Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(9, 36), // (10,29): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // Action a2 = x => { }; // parameter Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(10, 29), // (11,37): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // Action a3 = (string x) => { }; // parameter Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(11, 37), // (13,34): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // Action a4 = () => { void x() { } }; // method Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(13, 34), // (14,38): error CS1931: The range variable 'x' conflicts with a previous declaration of 'x' // Action a5 = () => { _ = from x in new[] { 1, 2, 3 } select x; }; // range variable Diagnostic(ErrorCode.ERR_QueryRangeVariableOverrides, "x").WithArguments("x").WithLocation(14, 38)); comp = CreateCompilation(source, parseOptions: TestOptions.Regular8); comp.VerifyDiagnostics(); comp = CreateCompilation(source); comp.VerifyDiagnostics(); } // PROTOTYPE: Need similar tests for queries as for lambdas. [Fact] public void ShadowNames_Parameter() { var source = @"#pragma warning disable 0219 #pragma warning disable 8321 using System; using System.Linq; class Program { static Action F = (object x) => { Action a1 = () => { object x = 0; }; // local Action a2 = x => { }; // parameter Action a3 = (string x) => { }; // parameter Action a4 = () => { void x() { } }; // method Action a5 = () => { _ = from x in new[] { 1, 2, 3 } select x; }; // range variable }; }"; var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3); comp.VerifyDiagnostics( // (9,36): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // Action a1 = () => { object x = 0; }; // local Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(9, 36), // (10,29): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // Action a2 = x => { }; // parameter Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(10, 29), // (11,37): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // Action a3 = (string x) => { }; // parameter Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(11, 37), // (13,38): error CS1931: The range variable 'x' conflicts with a previous declaration of 'x' // Action a5 = () => { _ = from x in new[] { 1, 2, 3 } select x; }; // range variable Diagnostic(ErrorCode.ERR_QueryRangeVariableOverrides, "x").WithArguments("x").WithLocation(13, 38)); comp = CreateCompilation(source); comp.VerifyDiagnostics(); } [Fact] public void ShadowNames_TypeParameter() { var source = @"#pragma warning disable 0219 #pragma warning disable 8321 using System; using System.Linq; class Program { static void M() { Action a1 = () => { object x = 0; }; // local Action a2 = x => { }; // parameter Action a3 = (string x) => { }; // parameter Action a4 = () => { void x() { } }; // method Action a5 = () => { _ = from x in new[] { 1, 2, 3 } select x; }; // range variable } }"; var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3); comp.VerifyDiagnostics( // (9,36): error CS0412: 'x': a parameter, local variable, or local function cannot have the same name as a method type parameter // Action a1 = () => { object x = 0; }; // local Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "x").WithArguments("x").WithLocation(9, 36), // (10,29): error CS0412: 'x': a parameter, local variable, or local function cannot have the same name as a method type parameter // Action a2 = x => { }; // parameter Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "x").WithArguments("x").WithLocation(10, 29), // (11,37): error CS0412: 'x': a parameter, local variable, or local function cannot have the same name as a method type parameter // Action a3 = (string x) => { }; // parameter Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "x").WithArguments("x").WithLocation(11, 37), // (12,34): error CS0412: 'x': a parameter, local variable, or local function cannot have the same name as a method type parameter // Action a4 = () => { void x() { } }; // method Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "x").WithArguments("x").WithLocation(12, 34), // (13,38): error CS1948: The range variable 'x' cannot have the same name as a method type parameter // Action a5 = () => { _ = from x in new[] { 1, 2, 3 } select x; }; // range variable Diagnostic(ErrorCode.ERR_QueryRangeVariableSameAsTypeParam, "x").WithArguments("x").WithLocation(13, 38)); comp = CreateCompilation(source); comp.VerifyDiagnostics(); } [Fact] public void ShadowNames_LambdaInsideLambda() { var source = @"#pragma warning disable 0219 #pragma warning disable 8321 using System; class Program { static void M(object x) { Action a1 = () => { Action b1 = () => { object x = 1; }; // local Action b2 = (string x) => { }; // parameter }; Action a2 = () => { Action b3 = () => { object T = 3; }; // local Action b4 = T => { }; // parameter }; } }"; var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3); comp.VerifyDiagnostics( // (10,40): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // Action b1 = () => { object x = 1; }; // local Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(10, 40), // (11,41): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // Action b2 = (string x) => { }; // parameter Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(11, 41), // (15,40): error CS0412: 'T': a parameter, local variable, or local function cannot have the same name as a method type parameter // Action b3 = () => { object T = 3; }; // local Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "T").WithArguments("T").WithLocation(15, 40), // (16,33): error CS0412: 'T': a parameter, local variable, or local function cannot have the same name as a method type parameter // Action b4 = T => { }; // parameter Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "T").WithArguments("T").WithLocation(16, 33)); comp = CreateCompilation(source); comp.VerifyDiagnostics(); } [Fact] public void ShadowNames_LambdaInsideLocalFunction_01() { var source = @"#pragma warning disable 0219 #pragma warning disable 8321 using System; class Program { static void M() { void F1() { object x = null; Action a1 = () => { int x = 0; }; } void F2() { Action a2 = () => { int T = 0; }; } } }"; var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3); comp.VerifyDiagnostics( // (11,37): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // Action a1 = () => { int x = 0; }; Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(11, 37), // (15,37): error CS0412: 'T': a parameter, local variable, or local function cannot have the same name as a method type parameter // Action a2 = () => { int T = 0; }; Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "T").WithArguments("T").WithLocation(15, 37)); comp = CreateCompilation(source); comp.VerifyDiagnostics(); } [Fact] public void ShadowNames_LambdaInsideLocalFunction_02() { var source = @"#pragma warning disable 0219 #pragma warning disable 8321 using System; class Program { static void M() { object x = null; void F() { Action a1 = (int x) => { Action b1 = () => { int T = 0; }; }; Action a2 = () => { int x = 0; Action b2 = (int T) => { }; }; } } }"; var comp = CreateCompilation(source, parseOptions: TestOptions.Regular7_3); comp.VerifyDiagnostics( // (11,35): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // Action a1 = (int x) => Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(11, 35), // (13,41): error CS0412: 'T': a parameter, local variable, or local function cannot have the same name as a method type parameter // Action b1 = () => { int T = 0; }; Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "T").WithArguments("T").WithLocation(13, 41), // (17,21): error CS0136: A local or parameter named 'x' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // int x = 0; Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "x").WithArguments("x").WithLocation(17, 21), // (18,39): error CS0412: 'T': a parameter, local variable, or local function cannot have the same name as a method type parameter // Action b2 = (int T) => { }; Diagnostic(ErrorCode.ERR_LocalSameNameAsTypeParam, "T").WithArguments("T").WithLocation(18, 39)); comp = CreateCompilation(source); comp.VerifyDiagnostics(); } } }