File: Symbols\ExtensionMethodTests.cs
Web Access
Project: src\src\Compilers\CSharp\Test\Symbol\Microsoft.CodeAnalysis.CSharp.Symbol.UnitTests.csproj (Microsoft.CodeAnalysis.CSharp.Symbol.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
#nullable disable
 
using System;
using System.Collections.Immutable;
using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Symbols.Metadata.PE;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
using Basic.Reference.Assemblies;
using Utils = Microsoft.CodeAnalysis.CSharp.UnitTests.CompilationUtils;
 
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.Symbols
{
    public class ExtensionMethodTests : CSharpTestBase
    {
        [ClrOnlyFact]
        public void IsExtensionMethod()
        {
            var source =
@"static class C
{
    internal static void M1(object o) { }
    internal static void M2(this object o) { }
    internal static void M3<T, U>(this T t, U u) { }
}";
            Action<ModuleSymbol> validator = module =>
            {
                var type = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
 
                // Ordinary method.
                var method = type.GetMember<MethodSymbol>("M1");
                Assert.False(method.IsExtensionMethod);
                var parameter = method.Parameters[0];
                Assert.Equal(SpecialType.System_Object, parameter.Type.SpecialType);
 
                // Extension method.
                method = type.GetMember<MethodSymbol>("M2");
                Assert.True(method.IsExtensionMethod);
                parameter = method.Parameters[0];
                Assert.Equal(SpecialType.System_Object, parameter.Type.SpecialType);
 
                // Extension method with type parameters.
                method = type.GetMember<MethodSymbol>("M3");
                Assert.True(method.IsExtensionMethod);
                parameter = method.Parameters[0];
                Assert.Equal(TypeKind.TypeParameter, parameter.Type.TypeKind);
            };
            CompileAndVerify(source, validator: validator, options: TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.Internal));
        }
 
        /// <summary>
        /// IsExtensionMethod should be false for
        /// invalid extension methods.
        /// </summary>
        [Fact]
        public void InvalidExtensionMethods()
        {
            var ilSource =
@".assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
.assembly extern System.Core {}
.assembly '<<GeneratedFileName>>'
{
    .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
}
.class public C
{
    .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
    .method public static void M1()
    {
        .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
        ret
    }
    .method public void M2(object o)
    {
        .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
        ret
    }
}
.class public S
{
    .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
    .method public static void M1()
    {
        .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
        ret
    }
    .method public static void M2([out] object& o)
    {
        .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
        ret
    }
    .method public static void M3(object[] o)
    {
        .param [1]
        .custom instance void [mscorlib]System.ParamArrayAttribute::.ctor() = ( 01 00 00 00 )
        .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
        ret
    }
}
";
            var source = @"class A
{
    internal static C F = null;
    internal static S G = null;
}";
            var compilation = CreateCompilationWithILAndMscorlib40(source, ilSource, appendDefaultHeader: false);
 
            var refType = compilation.Assembly.GlobalNamespace.GetMember<NamedTypeSymbol>("A");
            var type = (NamedTypeSymbol)refType.GetMember<FieldSymbol>("F").Type;
 
            // Static method no args.
            var method = type.GetMember<MethodSymbol>("M1");
            Assert.Equal(0, method.Parameters.Length);
            Assert.True(method.IsStatic);
            Assert.False(method.IsExtensionMethod);
 
            // Instance method.
            method = type.GetMember<MethodSymbol>("M2");
            Assert.Equal(1, method.Parameters.Length);
            Assert.False(method.IsStatic);
            Assert.False(method.IsExtensionMethod);
 
            type = (NamedTypeSymbol)refType.GetMember<FieldSymbol>("G").Type;
 
            // Static method no args.
            method = type.GetMember<MethodSymbol>("M1");
            Assert.Equal(0, method.Parameters.Length);
            Assert.True(method.IsStatic);
            Assert.False(method.IsExtensionMethod);
 
            // Static method out param.
            method = type.GetMember<MethodSymbol>("M2");
            Assert.Equal(1, method.Parameters.Length);
            Assert.True(method.IsStatic);
            Assert.False(method.IsExtensionMethod);
 
            // Static method params array.
            method = type.GetMember<MethodSymbol>("M3");
            Assert.Equal(1, method.Parameters.Length);
            Assert.True(method.IsStatic);
            Assert.False(method.IsExtensionMethod);
        }
 
        [ClrOnlyFact]
        public void OverloadResolution()
        {
            var source =
@"class C
{
    void N()
    {
        this.M(3);
        (new C()).M(0.5);
    }
}
static class S
{
    public static void M(this object o, int i) { }
    public static void M(this C c, int i) { }
    public static void M(this C c, double x) { }
}";
            CompileAndVerify(source);
        }
 
        [Fact]
        public void SameNameAsMember()
        {
            var source =
@"class C
{
    public object F = null;
    public object P { get; set; }
    public class T { }
    static void A(System.Action a) { }
    static void B(C c)
    {
        c.F(c.F);
        c.P(c.P);
        c.T();
        A(c.F);
        A(c.P);
        A(((object)c).F);
        A(((object)c).P);
    }
}
static class S
{
    public static void F(this object o) { }
    public static void F(this object x, object y) { }
    public static void P(this object o) { }
    public static void P(this object x, object y) { }
    public static void T(this object o) { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (12,11): error CS1503: Argument 1: cannot convert from 'object' to 'System.Action'
                Diagnostic(ErrorCode.ERR_BadArgType, "c.F").WithArguments("1", "object", "System.Action").WithLocation(12, 11),
                // (13,11): error CS1503: Argument 1: cannot convert from 'object' to 'System.Action'
                Diagnostic(ErrorCode.ERR_BadArgType, "c.P").WithArguments("1", "object", "System.Action").WithLocation(13, 11));
        }
 
        [WorkItem(529063, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529063")]
        [Fact]
        public void GetSymbolInfoTest()
        {
            var source =
@"static class S
{
    static void Goo(this string s) { }
    static void Main() { 
        string s = null;
        s.Goo();
    }
}";
            var compilation = CreateCompilation(source);
            var syntaxTree = compilation.SyntaxTrees.Single();
            var gooSymbol = (IMethodSymbol)compilation.GetSemanticModel(syntaxTree).GetSymbolInfo(
                syntaxTree.GetCompilationUnitRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().Single()).Symbol;
            Assert.True(gooSymbol.IsExtensionMethod);
            Assert.Equal(MethodKind.ReducedExtension, gooSymbol.MethodKind);
            var gooOriginal = gooSymbol.ReducedFrom;
            Assert.True(gooOriginal.IsExtensionMethod);
            Assert.Equal(MethodKind.Ordinary, gooOriginal.MethodKind);
        }
 
        [Fact]
        public void InaccessibleExtensionMethodSameNameAsMember()
        {
            var source =
@"class C
{
    public object F = null;
    public object P { get; set; }
    static void A(System.Action a) { }
    static void B(C c)
    {
        c.F();
        c.P();
        A(c.F);
        A(c.P);
    }
}
static class S
{
    private static void F(this object o) { }
    private static void P(this object o) { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (8,11): error CS1955: Non-invocable member 'C.F' cannot be used like a method.
                //         c.F();
                Diagnostic(ErrorCode.ERR_NonInvocableMemberCalled, "F").WithArguments("C.F"),
                // (9,11): error CS1955: Non-invocable member 'C.P' cannot be used like a method.
                //         c.P();
                Diagnostic(ErrorCode.ERR_NonInvocableMemberCalled, "P").WithArguments("C.P"),
                // (10,11): error CS1503: Argument 1: cannot convert from 'object' to 'System.Action'
                Diagnostic(ErrorCode.ERR_BadArgType, "c.F").WithArguments("1", "object", "System.Action").WithLocation(10, 11),
                // (11,11): error CS1503: Argument 1: cannot convert from 'object' to 'System.Action'
                Diagnostic(ErrorCode.ERR_BadArgType, "c.P").WithArguments("1", "object", "System.Action").WithLocation(11, 11));
        }
 
        [ClrOnlyFact]
        public void ExtensionMethodInTheSameClass()
        {
            var source =
@"using System;
static class Program
{
    static void Main()
    {
        ""ABC"".Goo();
        Action a = ""123"".Goo;
        a();
        a = new Action(a);
        a();
        a = new Action(""xyz"".Goo);
        a();
    }
    static void Goo(this string x)
    {
        Console.WriteLine(x);
    }
}";
            CompileAndVerify(source, expectedOutput:
@"ABC
123
123
xyz");
        }
 
        [WorkItem(541143, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541143")]
        [ClrOnlyFact]
        public void NumericConversionsAreNotAllowed()
        {
            var source =
@"
using System;
 
static class Program
{
    static void Main()
    {
        0.Goo();
    }
 
    static void Goo(this long x)
    {
        Console.WriteLine(""long"");
    }
 
    static void Goo(this object x)
    {
        Console.WriteLine(""object"");
    }
}
";
            CompileAndVerify(source, expectedOutput: "object");
        }
 
        [WorkItem(541144, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541144")]
        [ClrOnlyFact]
        public void EnumerationConversionsAreNotAllowed()
        {
            var source =
@"
using System;
 
static class Program
{
    static void Main()
    {
        0.Goo();
    }
 
    static void Goo(this DayOfWeek x)
    {
        Console.WriteLine(""DayOfWeek"");
    }
 
    static void Goo(this object x)
    {
        Console.WriteLine(""object"");
    }
}
";
            CompileAndVerify(source, expectedOutput: "object");
        }
 
        [WorkItem(541145, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541145")]
        [ClrOnlyFact]
        public void CannotCreateDelegateToExtensionMethodOnValueType()
        {
            var source =
@"
using System;
 
static class Program
{
    static void Main()
    {
        Bar(x => x.Goo);
    }
 
    static void Bar(Func<int, Action> x) { Console.WriteLine(1); }
    static void Bar(Func<object, Action> x) { Console.WriteLine(2); }
 
    static void Goo<T>(this T x) { }
}
";
            CompileAndVerify(source, expectedOutput: "2");
        }
 
        [WorkItem(528426, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528426")]
        [ClrOnlyFact]
        public void TypedReferenceCannotBeUsedAsTypeArgument()
        {
            var source =
@"
using System;
 
static class Program
{
    static void Main()
    {
        Bar(y => new TypedReference().Goo(y));
    }
 
    static void Bar(Action<string> a) { Console.WriteLine(1); }
    static void Bar(Action<int> a) { Console.WriteLine(2); }
 
    static void Goo<T>(this T x, string y) { }
    static void Goo(this TypedReference x, int y) { }
}
";
            CompileAndVerify(source, expectedOutput: "2");
        }
 
        [WorkItem(541146, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541146")]
        [WorkItem(868538, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/868538")]
        [Fact]
        public void VariablesUsedInExtensionMethodGroupMustBeDefinitelyAssigned()
        {
            var source =
@"
using System;
 
static class Program
{
    static void Main()
    {
        string s;
        bool x = s.Goo is Action;
 
        int i;
        bool y = i.Goo is Action;
    }
 
    static void Goo(this string x) { }
}
";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (9,18): error CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group.
                //         bool x = s.Goo is Action;
                Diagnostic(ErrorCode.ERR_LambdaInIsAs, "s.Goo is Action").WithLocation(9, 18),
                // (12,18): error CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group.
                //         bool y = i.Goo is Action;
                Diagnostic(ErrorCode.ERR_LambdaInIsAs, "i.Goo is Action").WithLocation(12, 18),
                // (9,18): error CS0165: Use of unassigned local variable 's'
                //         bool x = s.Goo is Action;
                Diagnostic(ErrorCode.ERR_UseDefViolation, "s").WithArguments("s").WithLocation(9, 18),
                // (12,18): error CS0165: Use of unassigned local variable 'i'
                //         bool y = i.Goo is Action;
                Diagnostic(ErrorCode.ERR_UseDefViolation, "i").WithArguments("i").WithLocation(12, 18)
                );
        }
 
        [WorkItem(541187, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541187")]
        [Fact]
        public void ExtensionMethodsCannotBeDeclaredInNamespaces()
        {
            var source =
@"
namespace N
{
    static void Goo(this int x) { }
}
";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (4,17): error CS0116: A namespace does not directly contain members such as fields or methods
                Diagnostic(ErrorCode.ERR_NamespaceUnexpected, "Goo"),
                // (4,17): error CS1106: Extension methods must be defined in a non-generic static class
                Diagnostic(ErrorCode.ERR_BadExtensionAgg, "Goo"));
        }
 
        [WorkItem(541189, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541189")]
        [ClrOnlyFact]
        public void ExtensionMethodsDeclaredInEnclosingNamespaceArePreferredOverImported2()
        {
            var source =
@"
using System;
using N;
 
static class Program
{
    static void Main()
    {
        """".Goo(1);
    }
 
    public static void Goo(this string x, object y) { Console.WriteLine(1); }
}
 
namespace N
{
    static class C
    {
        public static void Goo(this string x, int y) { Console.WriteLine(2); }
    }
}";
            CompileAndVerify(source, expectedOutput: "1");
        }
 
        [WorkItem(541189, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541189")]
        [ClrOnlyFact]
        public void ExtensionMethodsDeclaredInEnclosingNamespaceArePreferredOverImported()
        {
            var source =
@"
using System;
using N;
 
static class Program
{
    static void Main()
    {
        """".Goo();
    }
 
    public static void Goo(this string x) { Console.WriteLine(1); }
}
 
namespace N
{
    static class C
    {
        public static void Goo(this string x) { Console.WriteLine(2); }
    }
}
";
            CompileAndVerify(source, expectedOutput: "1");
        }
 
        [ClrOnlyFact]
        public void CandidateSearchByArgType()
        {
            var source =
@"static class A
{
    public static void E(this object o, double d) { }
}
namespace N1
{
    static class B
    {
        public static void E(this object o, bool b) { }
    }
}
namespace N1.N2
{
    static class C
    {
        public static void E(this object o, int i) { }
        static void Main()
        {
            1.E(2.0);
        }
    }
}";
            CompileAndVerify(source);
        }
 
        [ClrOnlyFact]
        public void CandidateSearchConversion()
        {
            var source =
@"interface I<T> { }
namespace N
{
    class C
    {
        static void M()
        {
            object o = 1.F1();
            o = 2.F2();
            o = 3.F3(1, 2, 3);
        }
    }
    static class S1
    {
        internal static void F1<T>(this I<T> t) { }
        internal static void F2(this double d) { }
        internal static void F3(this long l, params object[] args) { }
    }
}
static class S2
{
    internal static object F1<T>(this T t) { return null; }
    internal static object F2(this int i) { return null; }
    internal static object F3(this int i, params object[] args) { return null; }
}";
            CompileAndVerify(source);
        }
 
        /// <summary>
        /// Continue search for extension method candidates in certain
        /// cases where nearer candidates are not applicable.
        /// </summary>
        [Fact]
        public void CandidateSearch()
        {
            var source =
@"namespace N1
{
    namespace N2
    {
        partial class C
        {
            // Invalid calls with no extension methods in scope.
            void M()
            {
                this.M1(1, 2, 3); // MethodResolutionKind.NoCorrespondingParameter
                this.M2(1); // MethodResolutionKind.RequiredParameterMissing
                this.M3(1, 2.0); // MethodResolutionKind.BadArguments
                this.M4(null, 2); // MethodResolutionKind.TypeInferenceFailed
                this.M5<string, string>(null, 2); // Bad arity
                this.M6(null, null); // Ambiguous
            }
            void M1(int x, int y) { }
            void M2(int x, int y) { }
            void M3(int x, int y) { }
            void M3(int x, long y) { }
            void M4<T>(T x, int y) { }
            void M4<T>(T x, long y) { }
            void M5<T>(T x, int y) { }
            void M5<T>(T x, long y) { }
            void M6(object x, string y) { }
            void M6(string x, object y) { }
        }
    }
}
namespace N1
{
    using N4;
    namespace N2
    {
        using N3;
        partial class C
        {
            // Same calls as above but with N3.S and N4.S extension methods in scope.
            void N()
            {
                this.M1(1, 2, 3); // MethodResolutionKind.NoCorrespondingParameter
                this.M2(1); // MethodResolutionKind.RequiredParameterMissing
                this.M3(1, 2.0); // MethodResolutionKind.BadArguments
                this.M4(null, 2); // MethodResolutionKind.TypeInferenceFailed
                this.M5<string, string>(null, 2); // Bad arity
                this.M6(null, null); // Ambiguous
            }
        }
    }
}
namespace N3
{
    static class S
    {
        // Same signatures as instance methods above.
        public static void M1(this N1.N2.C c, int x, int y) { }
        public static void M2(this N1.N2.C c, int x, int y) { }
        public static void M3(this N1.N2.C c, int x, int y) { }
        public static void M3(this N1.N2.C c, int x, long y) { }
        public static void M4<T>(this N1.N2.C c, T x, int y) { }
        public static void M4<T>(this N1.N2.C c, T x, long y) { }
        public static void M5<T>(this N1.N2.C c, T x, int y) { }
        public static void M5<T>(this N1.N2.C c, T x, long y) { }
        public static void M6(this N1.N2.C c, object x, string y) { }
        public static void M6(this N1.N2.C c, string x, object y) { }
    }
}
namespace N4
{
    static class S
    {
        // Different signatures but also resulting in errors.
        public static void M1(this N1.N2.C c, string x, int y, int z) { }
        public static void M2(this N1.N2.C c, string x) { }
        public static void M3(this N1.N2.C c, string x) { }
        public static void M4(this N1.N2.C c, int x, int y) { }
        public static void M5<T, U>(this N1.N2.C c, T x, T y) { }
        public static void M6(this N1.N2.C c, int x, int y) { }
    }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (10,17): error CS1501: No overload for method 'M1' takes 3 arguments
                //                 this.M1(1, 2, 3); // MethodResolutionKind.NoCorrespondingParameter
                Diagnostic(ErrorCode.ERR_BadArgCount, "M1").WithArguments("M1", "3").WithLocation(10, 22),
                // (11,17): error CS7036: There is no argument given that corresponds to the required parameter 'y' of 'N1.N2.C.M2(int, int)'
                //                 this.M2(1); // MethodResolutionKind.RequiredParameterMissing
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M2").WithArguments("y", "N1.N2.C.M2(int, int)").WithLocation(11, 22),
                // (12,28): error CS1503: Argument 2: cannot convert from 'double' to 'int'
                //                 this.M3(1, 2.0); // MethodResolutionKind.BadArguments
                Diagnostic(ErrorCode.ERR_BadArgType, "2.0").WithArguments("2", "double", "int").WithLocation(12, 28),
                // (13,17): error CS0411: The type arguments for method 'N1.N2.C.M4<T>(T, int)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
                //                 this.M4(null, 2); // MethodResolutionKind.TypeInferenceFailed
                Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M4").WithArguments("N1.N2.C.M4<T>(T, int)").WithLocation(13, 22),
                // (14,22): error CS0305: Using the generic method 'N1.N2.C.M5<T>(T, int)' requires 1 type arguments
                //                 this.M5<string, string>(null, 2); // Bad arity
                Diagnostic(ErrorCode.ERR_BadArity, "M5<string, string>").WithArguments("N1.N2.C.M5<T>(T, int)", "method", "1").WithLocation(14, 22),
                // (15,17): error CS0121: The call is ambiguous between the following methods or properties: 'N1.N2.C.M6(object, string)' and 'N1.N2.C.M6(string, object)'
                //                 this.M6(null, null); // Ambiguous
                Diagnostic(ErrorCode.ERR_AmbigCall, "M6").WithArguments("N1.N2.C.M6(object, string)", "N1.N2.C.M6(string, object)").WithLocation(15, 22),
                // (41,17): error CS1501: No overload for method 'M1' takes 3 arguments
                //                 this.M1(1, 2, 3); // MethodResolutionKind.NoCorrespondingParameter
                Diagnostic(ErrorCode.ERR_BadArgCount, "M1").WithArguments("M1", "3").WithLocation(41, 22),
                // (42,17): error CS7036: There is no argument given that corresponds to the required parameter 'y' of 'N1.N2.C.M2(int, int)'
                //                 this.M2(1); // MethodResolutionKind.RequiredParameterMissing
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M2").WithArguments("y", "N1.N2.C.M2(int, int)").WithLocation(42, 22),
                // (43,28): error CS1503: Argument 2: cannot convert from 'double' to 'int'
                //                 this.M3(1, 2.0); // MethodResolutionKind.BadArguments
                Diagnostic(ErrorCode.ERR_BadArgType, "2.0").WithArguments("2", "double", "int").WithLocation(43, 28),
                // (44,17): error CS0411: The type arguments for method 'N1.N2.C.M4<T>(T, int)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
                //                 this.M4(null, 2); // MethodResolutionKind.TypeInferenceFailed
                Diagnostic(ErrorCode.ERR_CantInferMethTypeArgs, "M4").WithArguments("N1.N2.C.M4<T>(T, int)").WithLocation(44, 22),
                // (45,47): error CS1503: Argument 3: cannot convert from 'int' to 'string'
                //                 this.M5<string, string>(null, 2); // Bad arity
                Diagnostic(ErrorCode.ERR_BadArgType, "2").WithArguments("3", "int", "string").WithLocation(45, 47),
                // (46,17): error CS0121: The call is ambiguous between the following methods or properties: 'N1.N2.C.M6(object, string)' and 'N1.N2.C.M6(string, object)'
                //                 this.M6(null, null); // Ambiguous
                Diagnostic(ErrorCode.ERR_AmbigCall, "M6").WithArguments("N1.N2.C.M6(object, string)", "N1.N2.C.M6(string, object)").WithLocation(46, 22));
        }
 
        /// <summary>
        /// End search for extension method candidates
        /// if current method group is ambiguous.
        /// </summary>
        [Fact]
        public void EndSearchIfAmbiguous()
        {
            var source =
@"namespace N1
{
    internal static class S
    {
        public static void E(this object o, int x, object y) { }
        public static void E(this object o, double x, int y) { }
        public static void E(this object o, A x, B y) { }
    }
    class A { }
    class B { }
    namespace N2
    {
        internal static class S
        {
            public static void E(this object o, double x, A y) { }
            public static void E(this object o, double x, B y) { }
        }
        class C
        {
            static void M(object o)
            {
                o.E(1, null); // ambiguous
                o.E(1.0, 2.0); // N2.S.E(object, double, A)
                o.E(1.0, 2); // N1.S.E(object, double, int)
                o.E(null, null); // N1.S.E(object, A, B)
            }
        }
    }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (22,17): error CS0121: The call is ambiguous between the following methods or properties: 'N1.N2.S.E(object, double, N1.A)' and 'N1.N2.S.E(object, double, N1.B)'
                Diagnostic(ErrorCode.ERR_AmbigCall, "E").WithArguments("N1.N2.S.E(object, double, N1.A)", "N1.N2.S.E(object, double, N1.B)").WithLocation(22, 19),
                // (23,26): error CS1503: Argument 3: cannot convert from 'double' to 'N1.A'
                Diagnostic(ErrorCode.ERR_BadArgType, "2.0").WithArguments("3", "double", "N1.A").WithLocation(23, 26));
        }
 
        [Fact(Skip = "528425")]
        public void ParenthesizedMethodGroup()
        {
            var source =
@"static class S
{
    public static void E(this object a, object b) { }
    public static void E(this object o, int i) { }
    private static void E(this object o, object x, object y) { }
}
class C
{
    void E(int i, int j) { }
    void M()
    {
        ((this.E))(null);
        ((this.E))(null, null);
    }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (13, 9): error CS0122: 'S.E(object, object, object)' is inaccessible due to its protection level
                Diagnostic(ErrorCode.ERR_BadAccess, "((this.E))(null, null)").WithArguments("S.E(object, object, object)").WithLocation(13, 9));
        }
 
        [ClrOnlyFact]
        public void DelegateMembers()
        {
            var source =
@"using System;
class C
{
    public Action<int> F = A;
    public Action<int> P { get { return A; } }
    static void A(int i)
    {
        Console.WriteLine(i);
    }
    static void Main()
    {
        C c = new C();
        c.F(1);
        c.P(2);
    }
}";
            CompileAndVerify(source, expectedOutput:
@"1
2");
        }
 
        [Fact]
        public void DelegatesAndExtensionMethods()
        {
            var source =
@"using System;
class C
{
    public Action<int> F = A;
    public Action<int> P { get { return A; } }
    static void A(int i) { }
    void M()
    {
        this.F(1, 2);
        this.P(1.0);
    }
}
class D
{
    void F(int i) { }
    void P(int i) { }
    void M()
    {
        this.F(1, 2);
        this.P(2.0);
    }
}
static class S
{
    public static void F(this object o, int x, int y) { }
    public static void P(this object o, double d) { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (9, 9): error CS1593: Delegate 'System.Action<int>' does not take 2 arguments
                Diagnostic(ErrorCode.ERR_BadDelArgCount, "F").WithArguments("System.Action<int>", "2").WithLocation(9, 14),
                // (10,16): error CS1503: Argument 1: cannot convert from 'double' to 'int'
                Diagnostic(ErrorCode.ERR_BadArgType, "1.0").WithArguments("1", "double", "int").WithLocation(10, 16));
        }
 
        [ClrOnlyFact]
        public void DelegatesFromOverloads()
        {
            var source =
@"namespace N
{
    class C
    {
        void M(System.Action<object> a)
        {
            M(this.F);
            a = this.F;
            C c = new C();
            M(c.G);
            a = c.G;
        }
    }
    static class A
    {
        internal static void G(this C c) { }
    }
}
static class B
{
    internal static void F(this object o) { }
    internal static void F(this object x, object y) { }
    internal static void G(this object x, object y) { }
}";
            var compilation = CompileAndVerify(source);
            compilation.VerifyIL("N.C.M",
@"{
  // Code size       71 (0x47)
  .maxstack  3
  .locals init (N.C V_0) //c
  IL_0000:  ldarg.0
  IL_0001:  ldarg.0
  IL_0002:  ldftn      ""void B.F(object, object)""
  IL_0008:  newobj     ""System.Action<object>..ctor(object, System.IntPtr)""
  IL_000d:  call       ""void N.C.M(System.Action<object>)""
  IL_0012:  ldarg.0
  IL_0013:  ldftn      ""void B.F(object, object)""
  IL_0019:  newobj     ""System.Action<object>..ctor(object, System.IntPtr)""
  IL_001e:  starg.s    V_1
  IL_0020:  newobj     ""N.C..ctor()""
  IL_0025:  stloc.0
  IL_0026:  ldarg.0
  IL_0027:  ldloc.0
  IL_0028:  ldftn      ""void B.G(object, object)""
  IL_002e:  newobj     ""System.Action<object>..ctor(object, System.IntPtr)""
  IL_0033:  call       ""void N.C.M(System.Action<object>)""
  IL_0038:  ldloc.0
  IL_0039:  ldftn      ""void B.G(object, object)""
  IL_003f:  newobj     ""System.Action<object>..ctor(object, System.IntPtr)""
  IL_0044:  starg.s    V_1
  IL_0046:  ret
}");
        }
 
        [ClrOnlyFact]
        public void DelegatesAsArguments()
        {
            var source =
@"using System;
namespace N
{
    class C
    {
        static void M(object o)
        {
            o.M1(o.F1); // S1.M1(S1.F1)
            o.M1(o.F2); // S1.M1(S2.F2)
            o.M2(o.F3); // S2.M2(S1.F3)
            o.M2(o.F4); // S2.M2(S2.F4)
        }
    }
    static class S1
    {
        internal static void M1(this object o, Action<object> f) { }
        internal static void M2(this object o, Action f) { }
        internal static void F1(this object x, object y) { }
        internal static void F2(this object x, int y) { }
        internal static void F3(this object x, object y) { }
        internal static void F4(this object x, int y) { }
    }
}
static class S2
{
    internal static void M1(this object o, Action f) { }
    internal static void M2(this object o, Action<object> f) { }
    internal static void F1(this object x, int y) { }
    internal static void F2(this object x, object y) { }
    internal static void F3(this object x, int y) { }
    internal static void F4(this object x, object y) { }
}";
            var compilation = CompileAndVerify(source);
            compilation.VerifyIL("N.C.M",
@"
{
  // Code size       73 (0x49)
  .maxstack  3
  IL_0000:  ldarg.0
  IL_0001:  ldarg.0
  IL_0002:  ldftn      ""void N.S1.F1(object, object)""
  IL_0008:  newobj     ""System.Action<object>..ctor(object, System.IntPtr)""
  IL_000d:  call       ""void N.S1.M1(object, System.Action<object>)""
  IL_0012:  ldarg.0
  IL_0013:  ldarg.0
  IL_0014:  ldftn      ""void S2.F2(object, object)""
  IL_001a:  newobj     ""System.Action<object>..ctor(object, System.IntPtr)""
  IL_001f:  call       ""void N.S1.M1(object, System.Action<object>)""
  IL_0024:  ldarg.0
  IL_0025:  ldarg.0
  IL_0026:  ldftn      ""void N.S1.F3(object, object)""
  IL_002c:  newobj     ""System.Action<object>..ctor(object, System.IntPtr)""
  IL_0031:  call       ""void S2.M2(object, System.Action<object>)""
  IL_0036:  ldarg.0
  IL_0037:  ldarg.0
  IL_0038:  ldftn      ""void S2.F4(object, object)""
  IL_003e:  newobj     ""System.Action<object>..ctor(object, System.IntPtr)""
  IL_0043:  call       ""void S2.M2(object, System.Action<object>)""
  IL_0048:  ret
}");
        }
 
        [Fact]
        public void DelegatesFromInvalidOverloads()
        {
            var source =
@"namespace N
{
    class C
    {
        static void M1(System.Func<object, object> f) { }
        static void M2(System.Action<object> f) { }
        static void M()
        {
            C c = new C();
            M1(c.F1); // wrong return type
            M2(c.F1);
            M1(c.F2);
            M2(c.F2); // wrong return type
            M1(c.F3); // ambiguous
        }
    }
    static class S1
    {
        internal static void F1(this C c) { }
        internal static object F2(this C c) { return null; }
    }
}
static class S2
{
    internal static void F1(this object x, object y) { }
    internal static object F2(this N.C x, object y) { return null; }
    internal static object F3(this N.C x, object y) { return null; }
}
static class S3
{
    internal static object F3(this N.C x, object y) { return null; }
}";
            CreateCompilationWithMscorlib40(source, references: new[] { Net40.References.SystemCore },
                    parseOptions: TestOptions.WithoutImprovedOverloadCandidates).VerifyDiagnostics(
                // (10,16): error CS0407: 'void S2.F1(object, object)' has the wrong return type
                //             M1(c.F1); // wrong return type
                Diagnostic(ErrorCode.ERR_BadRetType, "c.F1").WithArguments("S2.F1(object, object)", "void").WithLocation(10, 16),
                // (13,16): error CS0407: 'object S2.F2(C, object)' has the wrong return type
                //             M2(c.F2); // wrong return type
                Diagnostic(ErrorCode.ERR_BadRetType, "c.F2").WithArguments("S2.F2(N.C, object)", "object").WithLocation(13, 16),
                // (14,16): error CS0121: The call is ambiguous between the following methods or properties: 'S2.F3(C, object)' and 'S3.F3(C, object)'
                //             M1(c.F3); // ambiguous
                Diagnostic(ErrorCode.ERR_AmbigCall, "c.F3").WithArguments("S2.F3(N.C, object)", "S3.F3(N.C, object)").WithLocation(14, 16));
            // NOTE: we have a degradation in the quality of diagnostics for a delegate conversion in this particular failure case.
            // See https://github.com/dotnet/roslyn/issues/24787
            // It is caused by a combination of two shortcomings  in the computation of diagnostics. First, in `BindExtensionMethod`
            // when we fail to find an applicable extension method, we only report a diagnostic for the first extension method group
            // that failed, even if some other extension method group contains a much better candidate. In the case of this test the first
            // extension method group contains a method with the wrong number of parameters, while the second one has an extension method
            // that fails only because of its return type mismatch.  Second, in
            // `OverloadResolutionResult<TMember>.ReportDiagnostics<T>`, we do not report a diagnostic for the failure
            // `MemberResolutionKind.NoCorrespondingParameter`, leaving it to the caller to notice that we failed to produce a
            // diagnostic (the caller has to grub through the diagnostic bag to see that there is no error there) and then the caller
            // has to produce a generic error message, which we see below. It does not appear that all callers have that test, though,
            // suggesting there may be a latent bug of missing diagnostics.
            CreateCompilationWithMscorlib40(source, references: new[] { Net40.References.SystemCore }).VerifyDiagnostics(
                // (10,16): error CS1503: Argument 1: cannot convert from 'method group' to 'Func<object, object>'
                //             M1(c.F1); // wrong return type
                Diagnostic(ErrorCode.ERR_BadArgType, "c.F1").WithArguments("1", "method group", "System.Func<object, object>").WithLocation(10, 16),
                // (13,16): error CS1503: Argument 1: cannot convert from 'method group' to 'Action<object>'
                //             M2(c.F2); // wrong return type
                Diagnostic(ErrorCode.ERR_BadArgType, "c.F2").WithArguments("1", "method group", "System.Action<object>").WithLocation(13, 16),
                // (14,16): error CS0121: The call is ambiguous between the following methods or properties: 'S2.F3(C, object)' and 'S3.F3(C, object)'
                //             M1(c.F3); // ambiguous
                Diagnostic(ErrorCode.ERR_AmbigCall, "c.F3").WithArguments("S2.F3(N.C, object)", "S3.F3(N.C, object)").WithLocation(14, 16));
        }
 
        [Fact]
        public void DelegatesAsInvalidArguments()
        {
            var source =
@"class A { }
class B { }
delegate A DA(DA a);
delegate B DB(DB b);
class C
{
    static void M()
    {
        M1(F);
        M2(F);
        M1(G(F));
        M2(G(F));
    }
    static void M1(DA f) { }
    static void M2(DB f) { }
    static A F(DA a) { return null; }
    static B F(DB b) { return null; }
    static DA G(DA f) { return f; }
    static DB G(DB f) { return f; }
}
namespace N
{
    class C
    {
        static void M(object o)
        {
            o.M1(o.F);
            o.M2(o.F);
            o.M1(G(o.F));
            o.M2(G(o.F));
        }
        static DA G(DA f) { return f; }
        static DB G(DB f) { return f; }
    }
    static class S1
    {
        internal static void M1(this object o, DA f) { }
        internal static void M2(this object o, DB f) { }
        internal static A F(this object o, DA a) { return null; }
    }
}
static class S2
{
    internal static B F(this object o, DB b) { return null; }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (11,12): error CS0121: The call is ambiguous between the following methods or properties: 'C.G(DA)' and 'C.G(DB)'
                Diagnostic(ErrorCode.ERR_AmbigCall, "G").WithArguments("C.G(DA)", "C.G(DB)").WithLocation(11, 12),
                // (12,12): error CS0121: The call is ambiguous between the following methods or properties: 'C.G(DA)' and 'C.G(DB)'
                Diagnostic(ErrorCode.ERR_AmbigCall, "G").WithArguments("C.G(DA)", "C.G(DB)").WithLocation(12, 12),
                // (29,18): error CS0121: The call is ambiguous between the following methods or properties: 'N.C.G(DA)' and 'N.C.G(DB)'
                Diagnostic(ErrorCode.ERR_AmbigCall, "G").WithArguments("N.C.G(DA)", "N.C.G(DB)").WithLocation(29, 18),
                // (30,18): error CS0121: The call is ambiguous between the following methods or properties: 'N.C.G(DA)' and 'N.C.G(DB)'
                Diagnostic(ErrorCode.ERR_AmbigCall, "G").WithArguments("N.C.G(DA)", "N.C.G(DB)").WithLocation(30, 18));
        }
 
        /// <summary>
        /// Extension methods should be resolved correctly even
        /// in cases where a method group is not allowed.
        /// </summary>
        [Fact]
        public void InvalidUseOfExtensionMethodGroup()
        {
            var source =
@"class C
{
    static void M(object o)
    {
        o.E += o.E;
        if (o.E != null)
        {
            M(o.E);
            o.E.ToString();
            o = !o.E;
        }
        o.F += o.F;
        if (o.F != null)
        {
            M(o.F);
            o.F.ToString();
            o = !o.F;
        }
        o.E.F();
    }
}
static class S
{
    internal static object E(this object o) { return null; }
    private static object F(this object o) { return null; }
}";
            var compilation = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            compilation.VerifyDiagnostics(
                // (5,9): error CS1656: Cannot assign to 'E' because it is a 'method group'
                //         o.E += o.E;
                Diagnostic(ErrorCode.ERR_AssgReadonlyLocalCause, "o.E").WithArguments("E", "method group").WithLocation(5, 9),
                // (6,13): error CS0019: Operator '!=' cannot be applied to operands of type 'method group' and '<null>'
                //         if (o.E != null)
                Diagnostic(ErrorCode.ERR_BadBinaryOps, "o.E != null").WithArguments("!=", "method group", "<null>").WithLocation(6, 13),
                // (8,15): error CS1503: Argument 1: cannot convert from 'method group' to 'object'
                //             M(o.E);
                Diagnostic(ErrorCode.ERR_BadArgType, "o.E").WithArguments("1", "method group", "object").WithLocation(8, 15),
                // (9,15): error CS0119: 'S.E(object)' is a method, which is not valid in the given context
                //             o.E.ToString();
                Diagnostic(ErrorCode.ERR_BadSKunknown, "E").WithArguments("S.E(object)", "method").WithLocation(9, 15),
                // (10,17): error CS0023: Operator '!' cannot be applied to operand of type 'method group'
                //             o = !o.E;
                Diagnostic(ErrorCode.ERR_BadUnaryOp, "!o.E").WithArguments("!", "method group").WithLocation(10, 17),
                // (12,11): error CS1061: 'object' does not contain a definition for 'F' and no accessible extension method 'F' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
                //         o.F += o.F;
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("object", "F").WithLocation(12, 11),
                // (12,18): error CS1061: 'object' does not contain a definition for 'F' and no accessible extension method 'F' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
                //         o.F += o.F;
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("object", "F").WithLocation(12, 18),
                // (13,15): error CS1061: 'object' does not contain a definition for 'F' and no accessible extension method 'F' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
                //         if (o.F != null)
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("object", "F").WithLocation(13, 15),
                // (15,17): error CS1061: 'object' does not contain a definition for 'F' and no accessible extension method 'F' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
                //             M(o.F);
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("object", "F").WithLocation(15, 17),
                // (16,15): error CS1061: 'object' does not contain a definition for 'F' and no accessible extension method 'F' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
                //             o.F.ToString();
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("object", "F").WithLocation(16, 15),
                // (17,20): error CS1061: 'object' does not contain a definition for 'F' and no accessible extension method 'F' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
                //             o = !o.F;
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("object", "F").WithLocation(17, 20),
                // (19,11): error CS0119: 'S.E(object)' is a method, which is not valid in the given context
                //         o.E.F();
                Diagnostic(ErrorCode.ERR_BadSKunknown, "E").WithArguments("S.E(object)", "method").WithLocation(19, 11)
            );
        }
 
        [Fact]
        public void Inaccessible()
        {
            var source =
@"using System;
class C
{
    static void M(object o)
    {
        o.F();
        M(o.F);
        Action a = o.F;
        o = o.F;
    }
    static void M(Action a) { }
}
static class S
{
    static void F(this object o) { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (6,11): error CS1061: 'object' does not contain a definition for 'F' and no extension method 'F' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
                //         o.F();
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("object", "F").WithLocation(6, 11),
                // (7,13): error CS1061: 'object' does not contain a definition for 'F' and no extension method 'F' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
                //         M(o.F);
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("object", "F").WithLocation(7, 13),
                // (8,22): error CS1061: 'object' does not contain a definition for 'F' and no extension method 'F' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
                //         Action a = o.F;
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("object", "F").WithLocation(8, 22),
                // (9,15): error CS1061: 'object' does not contain a definition for 'F' and no extension method 'F' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
                //         o = o.F;
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "F").WithArguments("object", "F").WithLocation(9, 15)
            );
        }
 
        [Fact(Skip = "528425")]
        public void InaccessibleAndAccessible()
        {
            var source =
@"using System;
namespace N
{
    class C
    {
        static void M(object o)
        {
            o.F(null);
            o.F();
            M1(o.F);
            M2(o.F);
            Action<object> a = o.F;
            Action b = o.F;
            o.G(); // no error
        }
        static void M1(Action<object> a) { }
        static void M2(Action a) { }
    }
    static class S1
    {
        static void F(this object o) { }
        internal static void F(this object x, object y) { }
        static void G(this object o) { }
    }
}
static class S2
{
    internal static void G(this object o) { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (9,9): error CS0122: 'S.F(object)' is inaccessible due to its protection level
                Diagnostic(ErrorCode.ERR_BadAccess, "F").WithArguments("S.F(object)").WithLocation(9, 9),
                // (11,9): error CS1503: Argument 1: cannot convert from 'method group' to 'System.Action'
                Diagnostic(ErrorCode.ERR_BadArgType, "o.F").WithArguments("1", "method group", "System.Action").WithLocation(11, 9),
                // (13,20): error CS0122: 'S.F(object)' is inaccessible due to its protection level
                Diagnostic(ErrorCode.ERR_BadAccess, "F").WithArguments("S.F(object)").WithLocation(13, 20));
        }
 
        /// <summary>
        /// Inaccessible instance member and
        /// extension method of same name.
        /// </summary>
        [Fact]
        public void InaccessibleInstanceMember()
        {
            var source =
@"using System;
class A
{
    void F() { }
    Action G;
    A H;
}
namespace N1
{
    class B
    {
        // No extension methods.
        static void M(A a)
        {
            a.F();
            a.G();
            a.H();
            M(a.F);
            M(a.G);
            M(a.H);
        }
        static void M(Action a) { }
    }
}
namespace N2
{
    class C
    {
        // Valid extension methods.
        static void M(A a)
        {
            a.F();
            a.G();
            a.H();
            M(a.F);
            M(a.G);
            M(a.H);
        }
        static void M(Action a) { }
    }
    static class S
    {
        internal static void F(this A a) { }
        internal static void G(this A a) { }
        internal static void H(this A a) { }
    }
}
namespace N3
{
    class C
    {
        // Inaccessible extension methods.
        static void M(A a)
        {
            a.F();
            a.G();
            a.H();
            M(a.F);
            M(a.G);
            M(a.H);
        }
        static void M(Action a) { }
    }
    static class S
    {
        static void F(this A a) { }
        static void G(this A a) { }
        static void H(this A a) { }
    }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (15,15): error CS0122: 'A.F()' is inaccessible due to its protection level
                //             a.F();
                Diagnostic(ErrorCode.ERR_BadAccess, "F").WithArguments("A.F()"),
                // (16,15): error CS0122: 'A.G' is inaccessible due to its protection level
                //             a.G();
                Diagnostic(ErrorCode.ERR_BadAccess, "G").WithArguments("A.G"),
                // (17,15): error CS1955: Non-invocable member 'A.H' cannot be used like a method.
                //             a.H();
                Diagnostic(ErrorCode.ERR_NonInvocableMemberCalled, "H").WithArguments("A.H"),
                // (18,17): error CS0122: 'A.F()' is inaccessible due to its protection level
                //             M(a.F);
                Diagnostic(ErrorCode.ERR_BadAccess, "F").WithArguments("A.F()"),
                // (19,17): error CS0122: 'A.G' is inaccessible due to its protection level
                //             M(a.G);
                Diagnostic(ErrorCode.ERR_BadAccess, "G").WithArguments("A.G"),
                // (20,17): error CS0122: 'A.H' is inaccessible due to its protection level
                //             M(a.H);
                Diagnostic(ErrorCode.ERR_BadAccess, "H").WithArguments("A.H"),
                // (55,15): error CS0122: 'A.F()' is inaccessible due to its protection level
                //             a.F();
                Diagnostic(ErrorCode.ERR_BadAccess, "F").WithArguments("A.F()"),
                // (56,15): error CS0122: 'A.G' is inaccessible due to its protection level
                //             a.G();
                Diagnostic(ErrorCode.ERR_BadAccess, "G").WithArguments("A.G"),
                // (57,15): error CS1955: Non-invocable member 'A.H' cannot be used like a method.
                //             a.H();
                Diagnostic(ErrorCode.ERR_NonInvocableMemberCalled, "H").WithArguments("A.H"),
                // (58,17): error CS0122: 'A.F()' is inaccessible due to its protection level
                //             M(a.F);
                Diagnostic(ErrorCode.ERR_BadAccess, "F").WithArguments("A.F()"),
                // (59,17): error CS0122: 'A.G' is inaccessible due to its protection level
                //             M(a.G);
                Diagnostic(ErrorCode.ERR_BadAccess, "G").WithArguments("A.G"),
                // (60,17): error CS0122: 'A.H' is inaccessible due to its protection level
                //             M(a.H);
                Diagnostic(ErrorCode.ERR_BadAccess, "H").WithArguments("A.H"),
                // (5,12): warning CS0169: The field 'A.G' is never used
                //     Action G;
                Diagnostic(ErrorCode.WRN_UnreferencedField, "G").WithArguments("A.G"),
                // (6,7): warning CS0169: The field 'A.H' is never used
                //     A H;
                Diagnostic(ErrorCode.WRN_UnreferencedField, "H").WithArguments("A.H"));
        }
 
        /// <summary>
        /// Method arguments should be evaluated,
        /// even if too many.
        /// </summary>
        [Fact]
        public void InaccessibleTooManyArgs()
        {
            var source =
@"static class S
{
    static void E(this object o) { }
}
class A
{
    static void F() { }
    void G() { }
}
class B
{
    static void M()
    {
        A a = null;
        M(a.E(), A.F(), a.G());
    }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (15,13): error CS1061: 'A' does not contain a definition for 'E' and no extension method 'E' accepting a first argument of type 'A' could be found (are you missing a using directive or an assembly reference?)
                //         M(a.E(), A.F(), a.G());
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "E").WithArguments("A", "E").WithLocation(15, 13),
                // (15,20): error CS0122: 'A.F()' is inaccessible due to its protection level
                //         M(a.E(), A.F(), a.G());
                Diagnostic(ErrorCode.ERR_BadAccess, "F").WithArguments("A.F()").WithLocation(15, 20),
                // (15,27): error CS0122: 'A.G()' is inaccessible due to its protection level
                //         M(a.E(), A.F(), a.G());
                Diagnostic(ErrorCode.ERR_BadAccess, "G").WithArguments("A.G()").WithLocation(15, 27)
            );
        }
 
        [WorkItem(541330, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541330")]
        [WorkItem(541335, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541335")]
        [Fact]
        public void ReturnDelegateAsObject()
        {
            var source =
@"class C
{
    static object M(object o)
    {
        return o.E;
    }
}
static class S
{
    internal static void E(this object o) { }
}";
 
            var compilation = CreateCompilation(source, parseOptions: TestOptions.Regular9);
            compilation.VerifyDiagnostics(
                // (5,18): error CS0428: Cannot convert method group 'E' to non-delegate type 'object'. Did you intend to invoke the method?
                Diagnostic(ErrorCode.ERR_MethGrpToNonDel, "E").WithArguments("E", "object").WithLocation(5, 18));
 
            compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (5,16): warning CS8974: Converting method group 'E' to non-delegate type 'object'. Did you intend to invoke the method?
                //         return o.E;
                Diagnostic(ErrorCode.WRN_MethGrpToNonDel, "o.E").WithArguments("E", "object").WithLocation(5, 16));
        }
 
        [Fact]
        public void AllExtensionMethodsInaccessible()
        {
            var source =
@"namespace N
{
    class A
    {
        void F() { }
    }
    class C
    {
        void M(A a)
        {
            a.F(); // instance and extension methods
            a.G(); // only extension methods
        }
    }
    static class S1
    {
        static void F(this object o) { }
        static void G(this object o) { }
    }
}
static class S2
{
    static void F(this object o) { }
    static void G(this object o) { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (11,15): error CS0122: 'A.F()' is inaccessible due to its protection level
                //             a.F(); // instance and extension methods
                Diagnostic(ErrorCode.ERR_BadAccess, "F").WithArguments("N.A.F()").WithLocation(11, 15),
                // (12,15): error CS1061: 'A' does not contain a definition for 'G' and no extension method 'G' accepting a first argument of type 'A' could be found (are you missing a using directive or an assembly reference?)
                //             a.G(); // only extension methods
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "G").WithArguments("N.A", "G").WithLocation(12, 15)
            );
        }
 
        [WorkItem(868538, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/868538")]
        [Fact]
        public void IsAndAs()
        {
            var source =
@"delegate void D();
static class S
{
    internal static void E(this object o) { }
}
class C
{
    static void M(C c)
    {
        if (F is D)
        {
            (F as D)();
        }
        if (c.F is D)
        {
            (c.F as D)();
        }
        if (G is D)
        {
            (G as D)();
        }
        if (c.E is D)
        {
            (c.E as D)();
        }
    }
    void F() { }
    static void G() { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (10,13): error CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group.
                //         if (F is D)
                Diagnostic(ErrorCode.ERR_LambdaInIsAs, "F is D").WithLocation(10, 13),
                // (12,14): error CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group.
                //             (F as D)();
                Diagnostic(ErrorCode.ERR_LambdaInIsAs, "F as D").WithLocation(12, 14),
                // (14,13): error CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group.
                //         if (c.F is D)
                Diagnostic(ErrorCode.ERR_LambdaInIsAs, "c.F is D").WithLocation(14, 13),
                // (16,14): error CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group.
                //             (c.F as D)();
                Diagnostic(ErrorCode.ERR_LambdaInIsAs, "c.F as D").WithLocation(16, 14),
                // (18,13): error CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group.
                //         if (G is D)
                Diagnostic(ErrorCode.ERR_LambdaInIsAs, "G is D").WithLocation(18, 13),
                // (20,14): error CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group.
                //             (G as D)();
                Diagnostic(ErrorCode.ERR_LambdaInIsAs, "G as D").WithLocation(20, 14),
                // (22,13): error CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group.
                //         if (c.E is D)
                Diagnostic(ErrorCode.ERR_LambdaInIsAs, "c.E is D").WithLocation(22, 13),
                // (24,14): error CS0837: The first operand of an 'is' or 'as' operator may not be a lambda expression, anonymous method, or method group.
                //             (c.E as D)();
                Diagnostic(ErrorCode.ERR_LambdaInIsAs, "c.E as D").WithLocation(24, 14));
        }
 
        [Fact]
        public void Casts()
        {
            var source =
@"delegate void D();
static class S
{
    internal static void E(this object o) { }
}
class C
{
    static void M(C c)
    {
        ((D)c.F)();
        ((D)G)();
        ((D)c.E)();
    }
    void F() { }
    static void G() { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics();
        }
 
        [Fact]
        public void NoReceiver()
        {
            var source =
@"class C
{
    void M()
    {
        E();
    }
}
static class S
{
    public static void E(this C c) { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                Diagnostic(ErrorCode.ERR_NameNotInContext, "E").WithArguments("E").WithLocation(5, 9));
        }
 
        [Fact]
        public void BaseReceiver()
        {
            var source =
@"class C
{
}
class D : C
{
    void M()
    {
        base.E();
    }
}
static class S
{
    public static void E(this C c) { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                Diagnostic(ErrorCode.ERR_NoSuchMember, "E").WithArguments("C", "E").WithLocation(8, 14));
        }
 
        [ClrOnlyFact]
        public void DefinedInSameClass()
        {
            var source =
@"static class C
{
    static void M(this string s, int i)
    {
        s.M(i + 1);
    }
}";
            CompileAndVerify(source);
        }
 
        /// <summary>
        /// Should not favor method from one class over another in same
        /// namespace, even if one method is defined in caller's class.
        /// </summary>
        [Fact]
        public void AmbiguousMethodDifferentClassesSameNamespace()
        {
            var source =
@"static class A
{
    public static void E(this string s, int i) { }
}
static class B
{
    public static void E(this string s, int i) { }
    static void M(string s)
    {
        s.E(1);
    }
}
static class C
{
    static void M(string s)
    {
        s.E(2);
    }
}
namespace N.S
{
    static class A
    {
        public static void E(this string s, int i) { }
    }
}
namespace N.S
{
    static class B
    {
        public static void E(this string s, int i) { }
        static void M(string s)
        {
            s.E(3);
        }
    }
    static class C
    {
        static void M(string s)
        {
            s.E(4);
        }
    }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                Diagnostic(ErrorCode.ERR_AmbigCall, "E").WithArgumentsAnyOrder("A.E(string, int)", "B.E(string, int)").WithLocation(10, 11),
                Diagnostic(ErrorCode.ERR_AmbigCall, "E").WithArgumentsAnyOrder("B.E(string, int)", "A.E(string, int)").WithLocation(17, 11),
                Diagnostic(ErrorCode.ERR_AmbigCall, "E").WithArguments("N.S.A.E(string, int)", "N.S.B.E(string, int)").WithLocation(34, 15),
                Diagnostic(ErrorCode.ERR_AmbigCall, "E").WithArguments("N.S.A.E(string, int)", "N.S.B.E(string, int)").WithLocation(41, 15));
        }
 
        /// <summary>
        /// Extension method delegates in different scopes make
        /// consumer (an overloaded method invocation) ambiguous.
        /// </summary>
        [Fact]
        public void AmbiguousConsumerWithExtensionMethodDelegateArg()
        {
            var source =
@"namespace N
{
    class C
    {
        static void M1(object o)
        {
            M2(o.F);
        }
        static void M2(System.Action a) { }
        static void M2(System.Action<int> a) { }
    }
    static class E
    {
        public static void F(this object o) { }
    }
}
static class E
{
    public static void F(this object o, int i) { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (7,13): error CS0121: The call is ambiguous between the following methods or properties: 'N.C.M2(System.Action)' and 'N.C.M2(System.Action<int>)'
                Diagnostic(ErrorCode.ERR_AmbigCall, "M2").WithArgumentsAnyOrder("N.C.M2(System.Action)", "N.C.M2(System.Action<int>)").WithLocation(7, 13));
        }
 
        /// <summary>
        /// Prefer methods on classes on inner namespaces.
        /// </summary>
        [ClrOnlyFact]
        public void InnerNamespacesBeforeOuter()
        {
            var source =
@"using System;
static class A
{
    public static void E(this string s)
    {
        Console.WriteLine(""A.E: {0}"", s);
    }
    public static void E(this string s, int i)
    {
        Console.WriteLine(""A.E: {0}, {1}"", s, i);
    }
    public static void E(this string s, bool b)
    {
        Console.WriteLine(""C.E: {0}, {1}"", s, b);
    }
}
namespace N1
{
    static class B
    {
        public static void E(this string s)
        {
            Console.WriteLine(""B.E: {0}"", s);
        }
        public static void E(this string s, bool b)
        {
            Console.WriteLine(""B.E: {0}, {1}"", s, b);
        }
    }
}
namespace N1.N2
{
    static class C
    {
        public static void E(this string s)
        {
            Console.WriteLine(""C.E: {0}"", s);
        }
    }
    namespace N3
    {
        static class D
        {
            public static void E(this string s)
            {
                Console.WriteLine(""D.E: {0}"", s);
            }
        }
    }
    static class E
    {
        static void Main()
        {
            ""str"".E();
            ""int"".E(1);
            ""bool"".E(true);
        }
    }
}";
            CompileAndVerify(source, expectedOutput:
@"C.E: str
A.E: int, 1
B.E: bool, True");
        }
 
        [Fact]
        public void ExtensionMethodsWithAccessorNames()
        {
            var source =
@"class C
{
    public object P { get; set; }
    void M()
    {
        this.set_P(this.get_P());
        set_P(get_P());
    }
}
class D
{
    static void M(C c)
    {
        c.set_P(c.get_P());
    }
}
static class S
{
    internal static object get_P(this C c) { return null; }
    static void set_P(this C c, object o) { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (6,14): error CS0571: 'C.P.set': cannot explicitly call operator or accessor
                Diagnostic(ErrorCode.ERR_CantCallSpecialMethod, "set_P").WithArguments("C.P.set").WithLocation(6, 14),
                // (7,9): error CS0571: 'C.P.set': cannot explicitly call operator or accessor
                Diagnostic(ErrorCode.ERR_CantCallSpecialMethod, "set_P").WithArguments("C.P.set").WithLocation(7, 9),
                // (7,15): error CS0571: 'C.P.get': cannot explicitly call operator or accessor
                Diagnostic(ErrorCode.ERR_CantCallSpecialMethod, "get_P").WithArguments("C.P.get").WithLocation(7, 15),
                // (14,11): error CS0571: 'C.P.set': cannot explicitly call operator or accessor
                Diagnostic(ErrorCode.ERR_CantCallSpecialMethod, "set_P").WithArguments("C.P.set").WithLocation(14, 11));
        }
 
        [Fact]
        public void DelegateExtensionMethodsWithAccessorNames()
        {
            var source =
@"using System;
class C
{
    object P { get; set; }
    object Q { get; set; }
    void M()
    {
        F(this.get_P);
        F(this.get_Q);
    }
    void F(Func<object> f) { }
}
static class S
{
    internal static object get_P(this C c) { return null; }
    static object get_Q(this C c) { return null; }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (9,16): error CS0571: 'C.Q.get': cannot explicitly call operator or accessor
                Diagnostic(ErrorCode.ERR_CantCallSpecialMethod, "get_Q").WithArguments("C.Q.get").WithLocation(9, 16));
        }
 
        [Fact]
        public void Delegates()
        {
            var source =
@"static class S
{
    public static void E(this object o) { }
    public static void F(this System.Action a) { }
    public static void G(this System.Action<object> a) { }
}
class C
{
    static void M()
    {
        S.F(4.E);
        S.F(new object().E);
        S.F(""str"".E);
        ""str"".E.F();
        (""str"".E).F();
        System.Action a = ""str"".E;
        a.F();
        S.G(S.E);
        S.E.G();
        System.Action<object> b = S.E;
        b.G();
    }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (14,15): error CS0119: 'S.E(object)' is a 'method', which is not valid in the given context
                Diagnostic(ErrorCode.ERR_BadSKunknown, "E").WithArguments("S.E(object)", "method").WithLocation(14, 15),
                // (15,16): error CS0119: 'S.E(object)' is a 'method', which is not valid in the given context
                Diagnostic(ErrorCode.ERR_BadSKunknown, "E").WithArguments("S.E(object)", "method").WithLocation(15, 16),
                // (19,11): error CS0119: 'S.E(object)' is a 'method', which is not valid in the given context
                Diagnostic(ErrorCode.ERR_BadSKunknown, "E").WithArguments("S.E(object)", "method").WithLocation(19, 11));
        }
 
        [ClrOnlyFact]
        public void GenericDelegate()
        {
            var source =
@"delegate void D<T>(T t);
class C
{
    static void Main()
    {
        F<int>(new C().M)(2);
    }
    static D<T> F<T>(D<T> d)
    {
        return d;
    }
    public int P { get { return 3; } }
}
static class S
{
    public static void M(this C c, int i)
    {
        System.Console.Write(c.P * i);
    }
}";
            CompileAndVerify(source, expectedOutput: "6");
        }
 
        [Fact]
        public void InvalidTypeArguments()
        {
            var source =
@"class C
{
    void M()
    {
        this.E<int>(1);
        this.E<S>();
        this.E<A>(null);
        this.E<int, int>(1);
    }
    void E<T>()
    {
    }
}
static class S
{
    public static void E<T>(this C c, T t)
    {
    }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (6,14): error CS0718: 'S': static types cannot be used as type arguments
                //         this.E<S>();
                Diagnostic(ErrorCode.ERR_GenericArgIsStaticClass, "E<S>").WithArguments("S").WithLocation(6, 14),
                // (7,16): error CS0246: The type or namespace name 'A' could not be found (are you missing a using directive or an assembly reference?)
                //         this.E<A>(null);
                Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "A").WithArguments("A").WithLocation(7, 16),
                // (8,14): error CS0305: Using the generic method 'C.E<T>()' requires 1 type arguments
                //         this.E<int, int>(1);
                Diagnostic(ErrorCode.ERR_BadArity, "E<int, int>").WithArguments("C.E<T>()", "method", "1").WithLocation(8, 14)
                );
        }
 
        [Fact]
        public void ThisArgumentConversions()
        {
            var source =
@"class A { }
class B { }
struct S { }
class C
{
    static void M()
    {
        A a = new A();
        a.A();
        a.B();
        a.O();
        a.T();
        B b = new B();
        b.A();
        b.B();
        b.O();
        S s = new S();
        s.A();
        s.S();
        s.O();
        s.T();
        (1.0).D();
        (2.0).O();
        1.A();
        2.O();
        3.T();
    }
}
static class Extensions
{
    internal static void A(this A a) { }
    internal static void B(this B b) { }
    internal static void S(this S s) { }
    internal static void T<U>(this U u) { }
    internal static void D(this double d) { }
    internal static void O(this object o) { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (10,9): error CS1929: 'A' does not contain a definition for 'B' and the best extension method overload 'Extensions.B(B)' requires a receiver of type 'B'
                //         a.B();
                Diagnostic(ErrorCode.ERR_BadInstanceArgType, "a").WithArguments("A", "B", "Extensions.B(B)", "B"),
                // (14,9): error CS1929: 'B' does not contain a definition for 'A' and the best extension method overload 'Extensions.A(A)' requires a receiver of type 'A'
                //         b.A();
                Diagnostic(ErrorCode.ERR_BadInstanceArgType, "b").WithArguments("B", "A", "Extensions.A(A)", "A"),
                // (18,9): error CS1929: 'S' does not contain a definition for 'A' and the best extension method overload 'Extensions.A(A)' requires a receiver of type 'A'
                //         s.A();
                Diagnostic(ErrorCode.ERR_BadInstanceArgType, "s").WithArguments("S", "A", "Extensions.A(A)", "A"),
                // (24,9): error CS1929: 'int' does not contain a definition for 'A' and the best extension method overload 'Extensions.A(A)' requires a receiver of type 'A'
                //         1.A();
                Diagnostic(ErrorCode.ERR_BadInstanceArgType, "1").WithArguments("int", "A", "Extensions.A(A)", "A")
                );
        }
 
        [Fact]
        public void ThisArgumentImplicitConversions()
        {
            var source =
@"class C
{
    static void M()
    {
        1.E1();
        2.E2();
        3.E3();
        4.E4();
    }
}
static class S
{
    internal static void E1<T>(this T t) { }
    internal static void E2(this double d) { }
    internal static void E3(this long l, params object[] args) { }
    internal static void E4(this object o) { }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (6,9): error CS1929: 'int' does not contain a definition for 'E2' and the best extension method overload 'S.E2(double)' requires a receiver of type 'double'
                //         2.E2();
                Diagnostic(ErrorCode.ERR_BadInstanceArgType, "2").WithArguments("int", "E2", "S.E2(double)", "double").WithLocation(6, 9),
                // (7,9): error CS1929: 'int' does not contain a definition for 'E3' and the best extension method overload 'S.E3(long, params object[])' requires a receiver of type 'long'
                //         3.E3();
                Diagnostic(ErrorCode.ERR_BadInstanceArgType, "3").WithArguments("int", "E3", "S.E3(long, params object[])", "long").WithLocation(7, 9));
        }
 
        [ClrOnlyFact]
        public void ParamsArray()
        {
            var source =
@"delegate void D(params int[] args);
class C
{
    void M()
    {
        this.E1(0);
        this.E1(1, null);
        1.E2();
        1.E2(2, 3);
        D d = this.E2;
    }
}
static class S
{
    internal static void E1(this C c, int i, params object[] args) { }
    internal static void E2(this object o, params int[] args) { }
}";
            CompileAndVerify(source);
        }
 
        [ClrOnlyFact]
        public void Using()
        {
            var source =
@"using System;
using N1.N2;
namespace N1
{
    internal static class S
    {
        public static void E(this object o) { Console.WriteLine(""N1.S.E""); }
    }
    namespace N2
    {
        internal static class S
        {
            public static void E(this object o) { Console.WriteLine(""N1.N2.S.E""); }
        }
    }
}
namespace N3
{
    internal static class S
    {
        public static void E(this object o) { Console.WriteLine(""N3.S.E""); }
    }
}
namespace N4
{
    using N3;
    class A
    {
        public static void M(object o) { o.E(); }
    }
}
namespace N4
{
    using N1;
    class B
    {
        public static void M(object o) { o.E(); }
    }
}
class C
{
    public static void M(object o) { o.E(); }
}
class D
{
    static void Main()
    {
        object o = null;
        N4.A.M(o);
        N4.B.M(o);
        C.M(o);
    }
}";
            var compilation = CompileAndVerify(source, expectedOutput:
@"N3.S.E
N1.S.E
N1.N2.S.E");
        }
 
        [Fact]
        public void AmbiguousUsing()
        {
            var source =
@"using N1;
using N2;
namespace N1
{
    internal static class S
    {
        public static void E(this object o) { }
    }
}
namespace N2
{
    internal static class S
    {
        public static void E(this object o) { }
    }
}
namespace N3
{
    internal static class S
    {
        public static void F(this object o) { }
        public static void G(this object o) { }
    }
}
namespace N4
{
    using N3;
    internal static class S
    {
        public static void F(this object o) { }
    }
    class C
    {
        static void M()
        {
            object o = null;
            o.E(); // ambiguous N1.S.E, N2.S.E
            o.F(); // choose N4.S.F over N3.S.F
            o.G(); // N3.S.G
        }
    }
}";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (37,13): error CS0121: The call is ambiguous between the following methods or properties: 'N1.S.E(object)' and 'N2.S.E(object)'
                Diagnostic(ErrorCode.ERR_AmbigCall, "E").WithArguments("N1.S.E(object)", "N2.S.E(object)").WithLocation(37, 15));
        }
 
        [Fact]
        public void VerifyDiagnosticForMissingSystemCoreReference()
        {
            var source =
@"
internal static class C
{
    internal static void M1(this object o) { }
    private static void Main(string[] args) { }
}
";
            var compilation = CreateEmptyCompilation(source, new[] { Net40.References.mscorlib });
            compilation.VerifyDiagnostics(
                // (4,29): error CS1110: Cannot define a new extension method because the compiler required type 'System.Runtime.CompilerServices.ExtensionAttribute' cannot be found. Are you missing a reference to System.Core.dll?
                Diagnostic(ErrorCode.ERR_ExtensionAttrNotFound, "this").WithArguments("System.Runtime.CompilerServices.ExtensionAttribute").WithLocation(4, 29));
        }
 
        [ClrOnlyFact]
        public void SystemLinqEnumerable()
        {
            var source =
@"using System;
using System.Linq;
class C
{
    static void Main()
    {
        string result = F(""banana"", ""orange"", ""lime"", ""apple"", ""kiwi"");
        Console.Write(result);
    }
    static string F(params string[] args)
    {
        return args.Skip(1).Where(Filter).Aggregate(Combine);
    }
    static string G(params string[] args)
    {
        return Enumerable.Aggregate(Enumerable.Where(Enumerable.Skip(args, 1), Filter), Combine);
    }
    static bool Filter(string s)
    {
        return s.Length > 4;
    }
    static string Combine(string s1, string s2)
    {
        return s1 + "", "" + s2;
    }
}";
            var code =
@"{
  // Code size       42 (0x2a)
  .maxstack  3
  IL_0000:  ldarg.0   
  IL_0001:  ldc.i4.1  
  IL_0002:  call       ""System.Collections.Generic.IEnumerable<string> System.Linq.Enumerable.Skip<string>(System.Collections.Generic.IEnumerable<string>, int)""
  IL_0007:  ldnull    
  IL_0008:  ldftn      ""bool C.Filter(string)""
  IL_000e:  newobj     ""System.Func<string, bool>..ctor(object, System.IntPtr)""
  IL_0013:  call       ""System.Collections.Generic.IEnumerable<string> System.Linq.Enumerable.Where<string>(System.Collections.Generic.IEnumerable<string>, System.Func<string, bool>)""
  IL_0018:  ldnull    
  IL_0019:  ldftn      ""string C.Combine(string, string)""
  IL_001f:  newobj     ""System.Func<string, string, string>..ctor(object, System.IntPtr)""
  IL_0024:  call       ""string System.Linq.Enumerable.Aggregate<string>(System.Collections.Generic.IEnumerable<string>, System.Func<string, string, string>)""
  IL_0029:  ret       
}";
            var compilation = CompileAndVerify(source, parseOptions: TestOptions.Regular10, expectedOutput: "orange, apple");
            compilation.VerifyIL("C.F", code);
            compilation.VerifyIL("C.G", code);
        }
 
        /// <summary>
        /// A value type should be boxed when used as a reference type receiver to an
        /// extension method. Note: Dev10 reports an error in such cases ("No overload for
        /// 'C.F(object)' matches delegate 'System.Action'") even though these cases are valid.
        /// </summary>
        [ClrOnlyFact]
        public void BoxingConversionOfDelegateReceiver01()
        {
            var source =
@"using System;
struct S { }
static class C
{
    static void Main()
    {
        M(1.F);
        M((new S()).F);
        M(1.G);
        M((new S()).G);
    }
    static void F(this object o)
    {
        Console.WriteLine(""F: {0}"", o.GetType());
    }
    static void G(this ValueType v)
    {
        Console.WriteLine(""G: {0}"", v.GetType());
    }
    static void M(Action a)
    {
        a();
    }
}";
            // ILVerify: Unrecognized arguments for delegate .ctor.
            var compilation = CompileAndVerify(source, expectedOutput:
@"F: System.Int32
F: S
G: System.Int32
G: S", verify: Verification.FailsILVerify);
            compilation.VerifyIL("C.Main",
@"{
  // Code size      105 (0x69)
  .maxstack  2
  .locals init (S V_0)
  IL_0000:  ldc.i4.1
  IL_0001:  box        ""int""
  IL_0006:  ldftn      ""void C.F(object)""
  IL_000c:  newobj     ""System.Action..ctor(object, System.IntPtr)""
  IL_0011:  call       ""void C.M(System.Action)""
  IL_0016:  ldloca.s   V_0
  IL_0018:  initobj    ""S""
  IL_001e:  ldloc.0
  IL_001f:  box        ""S""
  IL_0024:  ldftn      ""void C.F(object)""
  IL_002a:  newobj     ""System.Action..ctor(object, System.IntPtr)""
  IL_002f:  call       ""void C.M(System.Action)""
  IL_0034:  ldc.i4.1
  IL_0035:  box        ""int""
  IL_003a:  ldftn      ""void C.G(System.ValueType)""
  IL_0040:  newobj     ""System.Action..ctor(object, System.IntPtr)""
  IL_0045:  call       ""void C.M(System.Action)""
  IL_004a:  ldloca.s   V_0
  IL_004c:  initobj    ""S""
  IL_0052:  ldloc.0
  IL_0053:  box        ""S""
  IL_0058:  ldftn      ""void C.G(System.ValueType)""
  IL_005e:  newobj     ""System.Action..ctor(object, System.IntPtr)""
  IL_0063:  call       ""void C.M(System.Action)""
  IL_0068:  ret
}");
        }
 
        /// <summary>
        /// Similar to the test above, but using instances of type
        /// parameters for the delegate receiver.
        /// </summary>
        [ClrOnlyFact]
        public void BoxingConversionOfDelegateReceiver02()
        {
            var source =
@"using System;
interface I { }
class A { }
class B : A, I { }
class C
{
    static void Main()
    {
        M(new object(), new object(), 1, new B(), new B());
    }
    static void M<T1, T2, T3, T4, T5>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
        where T2 : class
        where T3 : struct
        where T4 : I
        where T5 : A
    {
        F(t1.M);
        F(t2.M);
        F(t3.M);
        F(t4.M);
        F(t5.M);
    }
    static void F(Action a)
    {
        a();
    }
}
static class E
{
    internal static void M(this object o)
    {
        Console.WriteLine(""{0}"", o.GetType());
    }
}";
            var compilation = CompileAndVerify(source, expectedOutput:
@"System.Object
System.Object
System.Int32
B
B");
            compilation.VerifyIL("C.M<T1, T2, T3, T4, T5>",
@"{
  // Code size      112 (0x70)
  .maxstack  2
  IL_0000:  ldarg.0
  IL_0001:  box        ""T1""
  IL_0006:  ldftn      ""void E.M(object)""
  IL_000c:  newobj     ""System.Action..ctor(object, System.IntPtr)""
  IL_0011:  call       ""void C.F(System.Action)""
  IL_0016:  ldarg.1
  IL_0017:  box        ""T2""
  IL_001c:  ldftn      ""void E.M(object)""
  IL_0022:  newobj     ""System.Action..ctor(object, System.IntPtr)""
  IL_0027:  call       ""void C.F(System.Action)""
  IL_002c:  ldarg.2
  IL_002d:  box        ""T3""
  IL_0032:  ldftn      ""void E.M(object)""
  IL_0038:  newobj     ""System.Action..ctor(object, System.IntPtr)""
  IL_003d:  call       ""void C.F(System.Action)""
  IL_0042:  ldarg.3
  IL_0043:  box        ""T4""
  IL_0048:  ldftn      ""void E.M(object)""
  IL_004e:  newobj     ""System.Action..ctor(object, System.IntPtr)""
  IL_0053:  call       ""void C.F(System.Action)""
  IL_0058:  ldarg.s    V_4
  IL_005a:  box        ""T5""
  IL_005f:  ldftn      ""void E.M(object)""
  IL_0065:  newobj     ""System.Action..ctor(object, System.IntPtr)""
  IL_006a:  call       ""void C.F(System.Action)""
  IL_006f:  ret
}");
        }
 
        [Fact]
        public void UsingInScript()
        {
            string test =
@"using System.Linq;
(new string[0]).Take(1)";
 
            var tree = SyntaxFactory.ParseSyntaxTree(test, options: TestOptions.Script.WithLanguageVersion(LanguageVersion.CSharp6));
 
            var compilation = CSharpCompilation.Create(
                assemblyName: GetUniqueName(),
                options: TestOptions.DebugExe.WithScriptClassName("Script"),
                syntaxTrees: new[] { tree },
                references: new[] { MscorlibRef, LinqAssemblyRef });
 
            var expr = ((ExpressionStatementSyntax)((GlobalStatementSyntax)tree.GetCompilationUnitRoot().Members[0]).Statement).Expression;
            var model = compilation.GetSemanticModel(tree);
            var info = model.GetSymbolInfo(expr);
            Assert.NotNull(info.Symbol);
            var symbol = info.Symbol;
            Utils.CheckSymbol(symbol, "IEnumerable<string> IEnumerable<string>.Take<string>(int count)");
        }
 
        [ClrOnlyFact]
        public void AssemblyMightContainExtensionMethods()
        {
            var source =
@"static class C
{
    internal static int F;
    internal static System.Linq.Expressions.Expression G;
    internal static void M(this object o) { }
}";
            Func<bool, Action<ModuleSymbol>> validator = isFromSource => module =>
            {
                var type = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
 
                // mscorlib.dll
                var mscorlib = type.GetMember<FieldSymbol>("F").Type.ContainingAssembly;
                Assert.Equal(RuntimeCorLibName.Name, mscorlib.Name);
                // We assume every PE assembly may contain extension methods.
                Assert.True(mscorlib.MightContainExtensionMethods);
 
                // TODO: Original references are not included in symbol validator.
                if (isFromSource)
                {
                    // System.Core.dll
                    var systemCore = type.GetMember<FieldSymbol>("G").Type.ContainingAssembly;
                    Assert.True(systemCore.MightContainExtensionMethods);
                }
 
                // Local assembly.
                var assembly = type.ContainingAssembly;
                Assert.True(assembly.MightContainExtensionMethods);
            };
 
            CompileAndVerify(
                source: source,
                sourceSymbolValidator: validator(true),
                symbolValidator: validator(false),
                options: TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.Internal));
        }
 
        /// <summary>
        /// AssemblySymbol.MightContainExtensionMethods should be reset after
        /// emit, after all types within the assembly have been inspected, if there
        /// are no types with extension methods.
        /// </summary>
        [ClrOnlyFact]
        public void AssemblyMightContainExtensionMethodsReset()
        {
            var source =
@"static class C
{
    internal static void M(object o) { }
}";
            AssemblySymbol sourceAssembly = null;
            Func<bool, Action<ModuleSymbol>> validator = isFromSource => module =>
            {
                var assembly = module.ContainingAssembly;
                var mightContainExtensionMethods = assembly.MightContainExtensionMethods;
                // Every PE assembly is assumed to be capable of having an extension method.
                // The source assembly doesn't know (so reports "true") until all methods have been inspected.
                Assert.True(mightContainExtensionMethods);
                if (isFromSource)
                {
                    Assert.Null(sourceAssembly);
                    sourceAssembly = assembly;
                }
            };
            CompileAndVerify(source, symbolValidator: validator(false), sourceSymbolValidator: validator(true));
            Assert.NotNull(sourceAssembly);
            Assert.False(sourceAssembly.MightContainExtensionMethods);
        }
 
        [ClrOnlyFact]
        public void ReducedExtensionMethodSymbols()
        {
            var source =
@"using System.Collections.Generic;
static class S
{
    internal static void M1(this object o) { }
    internal static void M2<T>(this IEnumerable<T> t) { }
    internal static void M3<T, U>(this U u, IEnumerable<T> t) { }
}";
            var compilation = CreateCompilation(source, options: TestOptions.ReleaseDll.WithMetadataImportOptions(MetadataImportOptions.Internal));
            Action<ModuleSymbol> validator = module =>
            {
                var type = module.GlobalNamespace.GetMember<NamedTypeSymbol>("S");
                var intType = compilation.GetSpecialType(SpecialType.System_Int32);
                var stringType = compilation.GetSpecialType(SpecialType.System_String);
                var arrayType = ArrayTypeSymbol.CreateCSharpArray(compilation.Assembly, TypeWithAnnotations.Create(stringType), 1);
 
                // Non-generic method.
                var method = type.GetMember<MethodSymbol>("M1");
                CheckExtensionMethod(method,
                    ImmutableArray.Create<TypeWithAnnotations>(),
                    "void object.M1()",
                    "void S.M1(object o)",
                    "void object.M1()",
                    "void S.M1(object o)");
 
                // Generic method, one type argument.
                method = type.GetMember<MethodSymbol>("M2");
                CheckExtensionMethod(method,
                    ImmutableArray.Create(TypeWithAnnotations.Create(intType)),
                    "void IEnumerable<int>.M2<int>()",
                    "void S.M2<T>(IEnumerable<T> t)",
                    "void IEnumerable<T>.M2<T>()",
                    "void S.M2<T>(IEnumerable<T> t)");
 
                // Generic method, multiple type arguments.
                method = type.GetMember<MethodSymbol>("M3");
                CheckExtensionMethod(method,
                    ImmutableArray.Create(TypeWithAnnotations.Create(intType), TypeWithAnnotations.Create(arrayType)),
                    "void string[].M3<int, string[]>(IEnumerable<int> t)",
                    "void S.M3<T, U>(U u, IEnumerable<T> t)",
                    "void U.M3<T, U>(IEnumerable<T> t)",
                    "void S.M3<T, U>(U u, IEnumerable<T> t)");
            };
 
            CompileAndVerify(compilation, sourceSymbolValidator: validator, symbolValidator: validator);
        }
 
        private void CheckExtensionMethod(
            MethodSymbol method,
            ImmutableArray<TypeWithAnnotations> typeArgs,
            string reducedMethodDescription,
            string reducedFromDescription,
            string constructedFromDescription,
            string reducedAndConstructedFromDescription)
        {
            // Create instance form from constructed method.
            var extensionMethod = ReducedExtensionMethodSymbol.Create(method.ConstructIfGeneric(typeArgs));
            Utils.CheckReducedExtensionMethod(extensionMethod, reducedMethodDescription, reducedFromDescription, constructedFromDescription, reducedAndConstructedFromDescription);
 
            // Construct method from unconstructed instance form.
            extensionMethod = ReducedExtensionMethodSymbol.Create(method).ConstructIfGeneric(typeArgs);
            Utils.CheckReducedExtensionMethod(extensionMethod, reducedMethodDescription, reducedFromDescription, constructedFromDescription, reducedAndConstructedFromDescription);
        }
 
        /// <summary>
        /// Roslyn bug 7782: NullRef in PeWriter.DebuggerShouldHideMethod
        /// </summary>
        [Fact]
        public void ExtensionMethod_ValidateExtensionAttribute()
        {
            var comp = CreateCompilation(@"
using System;
internal static class C
{
    internal static void M1(this object o) { }
    private static void Main(string[] args) { }
}
", options: TestOptions.DebugExe.WithMetadataImportOptions(MetadataImportOptions.All));
 
            CompileAndVerify(comp, symbolValidator: module =>
            {
                var method = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C").GetMember<PEMethodSymbol>("M1");
                Assert.True(method.IsExtensionMethod);
                Assert.Equal(SpecialType.System_Object, method.Parameters.Single().Type.SpecialType);
 
                var attr = ((PEModuleSymbol)module).GetCustomAttributesForToken(method.Handle).Single();
                Assert.Equal("System.Runtime.CompilerServices.ExtensionAttribute", attr.AttributeClass.ToTestDisplayString());
            });
        }
 
        [WorkItem(541327, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541327")]
        [Fact]
        public void RegressBug7992()
        {
            var text =
@"using System.Runtime.InteropServices;
namespace ConsoleApplication1
{
    [StructLayout(Pack = A.B)]
    struct Program { }
}
";
            CreateCompilation(text).GetDiagnostics();
        }
 
        /// <summary>
        /// Box value type receiver if passed as reference type.
        /// </summary>
        [ClrOnlyFact]
        public void BoxValueTypeReceiverIfNecessary()
        {
            var source =
@"struct S { }
static class C
{
    static void Main()
    {
        ""str"".F();
        ""str"".G();
        (2.0).F();
        (2.0).G();
        (new S()).F();
        (new S()).G();
    }
    static void F(this object o)
    {
        System.Console.WriteLine(""{0}"", o.ToString());
    }
    static void G<T>(this T t)
    {
        System.Console.WriteLine(""{0}"", t.ToString());
    }
}";
            var compilation = CompileAndVerify(source, expectedOutput:
@"str
str
2
2
S
S");
            compilation.VerifyIL("C.Main",
@"{
  // Code size       87 (0x57)
  .maxstack  1
  .locals init (S V_0)
  IL_0000:  ldstr      ""str""
  IL_0005:  call       ""void C.F(object)""
  IL_000a:  ldstr      ""str""
  IL_000f:  call       ""void C.G<string>(string)""
  IL_0014:  ldc.r8     2
  IL_001d:  box        ""double""
  IL_0022:  call       ""void C.F(object)""
  IL_0027:  ldc.r8     2
  IL_0030:  call       ""void C.G<double>(double)""
  IL_0035:  ldloca.s   V_0
  IL_0037:  initobj    ""S""
  IL_003d:  ldloc.0
  IL_003e:  box        ""S""
  IL_0043:  call       ""void C.F(object)""
  IL_0048:  ldloca.s   V_0
  IL_004a:  initobj    ""S""
  IL_0050:  ldloc.0
  IL_0051:  call       ""void C.G<S>(S)""
  IL_0056:  ret
}");
        }
 
        [WorkItem(541652, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541652")]
        [ClrOnlyFact]
        public void ReduceExtensionMethodWithNullReceiverType()
        {
            var source =
@"static class Extensions
{
    public static int NonGeneric(this object o) { return o.GetHashCode(); }
    public static int Generic<T>(this T o) { return o.GetHashCode(); }
}
";
            CompileAndVerify(source, validator: module =>
            {
                var type = module.GlobalNamespace.GetMember<NamedTypeSymbol>("Extensions");
                var nonGenericExtension = type.GetMember<MethodSymbol>("NonGeneric");
                var genericExtension = type.GetMember<MethodSymbol>("Generic");
 
                Assert.True(nonGenericExtension.IsExtensionMethod);
                Assert.Throws<ArgumentNullException>(() => nonGenericExtension.ReduceExtensionMethod(receiverType: null, compilation: null!));
 
                Assert.True(genericExtension.IsExtensionMethod);
                Assert.Throws<ArgumentNullException>(() => genericExtension.ReduceExtensionMethod(receiverType: null, compilation: null!));
            });
        }
 
        [WorkItem(528730, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528730")]
        [Fact]
        public void ThisParameterCalledOnNonSourceMethodSymbol()
        {
            var code =
@"using System.Collections.Generic;
using System.Linq;
 
class Program
{
    static void Main(string[] args)
    {
        int[] numbers = new int[] { 4, 5 };
        int i1 = numbers.GetHashCode();
        int i2 = numbers.Cast<T1>();
    }
}";
            var compilation = CreateCompilationWithMscorlib40AndSystemCore(code);
            var tree = compilation.SyntaxTrees[0];
            var model = compilation.GetSemanticModel(tree);
 
            var node = tree.GetCompilationUnitRoot().FindToken(code.IndexOf("GetHashCode", StringComparison.Ordinal)).Parent;
            var symbolInfo = model.GetSymbolInfo((SimpleNameSyntax)node);
            var methodSymbol = symbolInfo.Symbol.GetSymbol<MethodSymbol>();
            Assert.False(methodSymbol.IsFromCompilation(compilation));
 
            var parameter = methodSymbol.ThisParameter;
            Assert.Equal(-1, parameter.Ordinal);
            Assert.Equal(parameter.ContainingSymbol, methodSymbol);
 
            // Get the GenericNameSyntax node Cast<T1> for binding
            node = tree.GetCompilationUnitRoot().FindToken(code.IndexOf("Cast<T1>", StringComparison.Ordinal)).Parent;
            symbolInfo = model.GetSymbolInfo((GenericNameSyntax)node);
            methodSymbol = (MethodSymbol)symbolInfo.Symbol.GetSymbol<MethodSymbol>();
            Assert.False(methodSymbol.IsFromCompilation(compilation));
 
            // 9341 is resolved as Won't Fix since ThisParameter property is internal.
            Assert.Throws<InvalidOperationException>(() => methodSymbol.ThisParameter);
        }
 
        private CompilationVerifier CompileAndVerify(string source, string expectedOutput = null, Action<ModuleSymbol> validator = null,
            CSharpCompilationOptions options = null)
        {
            return CompileAndVerify(
                source: source,
                expectedOutput: expectedOutput,
                sourceSymbolValidator: validator,
                symbolValidator: validator,
                options: options);
        }
 
        [WorkItem(528853, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528853")]
        [Fact]
        public void NoOverloadTakesNArguments()
        {
            var source =
@"static class S
{
    static void M(this object x, object y)
    {
        x.M(x, y);
        x.M();
        M(x);
    }
}";
            CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics(
                // (5,9): error CS1501: No overload for method 'M' takes 2 arguments
                //         x.M(x, y);
                Diagnostic(ErrorCode.ERR_BadArgCount, "M").WithArguments("M", "2").WithLocation(5, 11),
                // (6,9): error CS7036: There is no argument given that corresponds to the required parameter 'y' of 'S.M(object, object)'
                //         x.M();
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("y", "S.M(object, object)").WithLocation(6, 11),
                // (7,9): error CS7036: There is no argument given that corresponds to the required parameter 'y' of 'S.M(object, object)'
                //         M(x);
                Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("y", "S.M(object, object)").WithLocation(7, 9));
        }
 
        [WorkItem(543711, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543711")]
        [Fact]
        public void ReduceReducedExtensionsMethod()
        {
            var source =
@"static class C
{
    static void M(this object x)
    {
    }
}";
            var compilation = CreateCompilationWithMscorlib40AndSystemCore(source);
            compilation.VerifyDiagnostics();
 
            var extensionMethod = compilation.GlobalNamespace.GetMember<NamedTypeSymbol>("C").GetMember<MethodSymbol>("M");
            Assert.True(extensionMethod.IsExtensionMethod);
 
            var reduced = extensionMethod.ReduceExtensionMethod();
            Assert.True(reduced.IsExtensionMethod);
 
            Assert.Null(reduced.ReduceExtensionMethod());
 
            var int32Type = compilation.GetSpecialType(SpecialType.System_Int32);
 
            var reducedWithReceiver = extensionMethod.ReduceExtensionMethod(int32Type, null!);
            Assert.True(reduced.IsExtensionMethod);
            Assert.Equal(reduced, reducedWithReceiver);
 
            Assert.Null(reducedWithReceiver.ReduceExtensionMethod(int32Type, null!));
        }
 
        [WorkItem(37780, "https://github.com/dotnet/roslyn/issues/37780")]
        [Fact]
        public void ReducedExtensionMethodVsUnmanagedConstraint()
        {
            var source1 =
@"public static class C
{
    public static void M<T>(this T self) where T : unmanaged
    {
    }
}";
            var compilation1 = CreateCompilation(source1);
            compilation1.VerifyDiagnostics();
 
            var source2 =
@"public class D
{
    static void M(MyStruct<int> s)
    {
        s.M();
    }
}
public struct MyStruct<T>
{
    public T field;
}
";
 
            var compilation2 = CreateCompilation(source2, references: new[] { new CSharpCompilationReference(compilation1) }, parseOptions: TestOptions.Regular8);
            compilation2.VerifyDiagnostics();
 
            var extensionMethod = compilation2.GlobalNamespace.GetMember<NamedTypeSymbol>("C").GetMember<MethodSymbol>("M");
            Assert.True(extensionMethod.IsExtensionMethod);
 
            var myStruct = (NamedTypeSymbol)compilation2.GlobalNamespace.GetMember<NamedTypeSymbol>("MyStruct");
            var int32Type = compilation2.GetSpecialType(SpecialType.System_Int32);
            var msi = myStruct.Construct(int32Type);
 
            object reducedWithReceiver = extensionMethod.ReduceExtensionMethod(msi, compilation2);
            Assert.NotNull(reducedWithReceiver);
 
            reducedWithReceiver = extensionMethod.ReduceExtensionMethod(msi, null!);
            Assert.NotNull(reducedWithReceiver);
 
            reducedWithReceiver = extensionMethod.GetPublicSymbol().ReduceExtensionMethod(msi.GetPublicSymbol());
            Assert.NotNull(reducedWithReceiver);
 
            compilation2 = CreateCompilation(source2, references: new[] { new CSharpCompilationReference(compilation1) }, parseOptions: TestOptions.Regular7);
            compilation2.VerifyDiagnostics(
                // (5,9): error CS8107: Feature 'unmanaged constructed types' is not available in C# 7.0. Please use language version 8.0 or greater.
                //         s.M();
                Diagnostic(ErrorCode.ERR_FeatureNotAvailableInVersion7, "s.M").WithArguments("unmanaged constructed types", "8.0").WithLocation(5, 9)
                );
 
            extensionMethod = compilation2.GlobalNamespace.GetMember<NamedTypeSymbol>("C").GetMember<MethodSymbol>("M");
            Assert.True(extensionMethod.IsExtensionMethod);
 
            myStruct = (NamedTypeSymbol)compilation2.GlobalNamespace.GetMember<NamedTypeSymbol>("MyStruct");
            int32Type = compilation2.GetSpecialType(SpecialType.System_Int32);
            msi = myStruct.Construct(int32Type);
 
            reducedWithReceiver = extensionMethod.ReduceExtensionMethod(msi, compilation2);
            Assert.Null(reducedWithReceiver);
 
            reducedWithReceiver = extensionMethod.ReduceExtensionMethod(msi, null!);
            Assert.NotNull(reducedWithReceiver);
 
            reducedWithReceiver = extensionMethod.GetPublicSymbol().ReduceExtensionMethod(msi.GetPublicSymbol());
            Assert.NotNull(reducedWithReceiver);
        }
 
        /// <summary>
        /// Dev11 reports error for inaccessible extension method in addition to an
        /// error for the instance method that was used for binding. The inaccessible
        /// error may be helpful for the user or for "quick fix" in particular.
        /// </summary>
        [WorkItem(529866, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529866")]
        [Fact]
        public void InstanceMethodAndInaccessibleExtensionMethod_Diagnostics()
        {
            var source =
@"class C
{
    static void Main()
    {
        C c = new C();
        c.Test(1d);
    }
    void Test(float f)
    {
    }
}
static class Extensions
{
    static void Test(this C c, double d)
    {
    }
    static void Test<T>(this T t)
    {
    }
}";
            // Dev11 also reports:
            // (17,17): error CS0122: 'Extensions.Test<T>(T)' is inaccessible due to its protection level
            CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics(
                // (6,16): error CS1503: Argument 1: cannot convert from 'double' to 'float'
                Diagnostic(ErrorCode.ERR_BadArgType, "1d").WithArguments("1", "double", "float").WithLocation(6, 16));
        }
 
        [WorkItem(545322, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545322")] // Bug relates to defunct LookupOptions.IgnoreAccessibility.
        [Fact]
        public void InstanceMethodAndInaccessibleExtensionMethod_Symbols()
        {
            var source =
@"class C
{
    static void Main()
    {
        C c = new C();
        c.Test(1d);
    }
    void Test(float f)
    {
    }
}
static class Extensions
{
    static void Test(this C c, double d)
    {
    }
    static void Test<T>(this T t)
    {
    }
}";
            var compilation = (Compilation)CreateCompilationWithMscorlib40AndSystemCore(source);
            var globalNamespace = compilation.GlobalNamespace;
            var type = globalNamespace.GetMember<INamedTypeSymbol>("C");
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
            var memberAccess = tree.GetCompilationUnitRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().Single();
 
            var lookupResult = model.LookupSymbols(
                memberAccess.SpanStart,
                container: null,
                name: "Test",
                includeReducedExtensionMethods: true);
            Utils.CheckISymbols(lookupResult,
                "void C.Test(float f)");
 
            lookupResult = model.LookupSymbols(
                memberAccess.SpanStart,
                container: type,
                name: "Test",
                includeReducedExtensionMethods: true);
            Utils.CheckISymbols(lookupResult,
                "void C.Test(float f)"); // Extension methods not found.
 
            var memberGroup = model.GetMemberGroup(memberAccess);
            Utils.CheckISymbols(memberGroup,
                "void C.Test(float f)");
 
            compilation.VerifyDiagnostics(
                // (6,16): error CS1503: Argument 1: cannot convert from 'double' to 'float'
                //         c.Test(1d);
                Diagnostic(ErrorCode.ERR_BadArgType, "1d").WithArguments("1", "double", "float"));
        }
 
        [WorkItem(541890, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541890")]
        [Fact]
        public void InstanceMethodAndInaccessibleExtensionMethod_CandidateSymbols()
        {
            var source =
@"class C
{
    static void Main()
    {
        C c = new C();
        c.Test(1d);
    }
    void Test(float f)
    {
    }
}
static class Extensions
{
    static void Test(this C c, double d)
    {
    }
    static void Test<T>(this T t)
    {
    }
}";
            var compilation = (Compilation)CreateCompilationWithMscorlib40AndSystemCore(source);
            var globalNamespace = compilation.GlobalNamespace;
            var type = globalNamespace.GetMember<INamedTypeSymbol>("C");
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
            var memberAccess = tree.GetCompilationUnitRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().Single();
 
            var call = (ExpressionSyntax)memberAccess.Parent;
            Assert.Equal(SyntaxKind.InvocationExpression, call.Kind());
 
            var info = model.GetSymbolInfo(call);
            Assert.Null(info.Symbol);
            Assert.Equal(CandidateReason.OverloadResolutionFailure, info.CandidateReason);
            // Definitely want the extension method here for quick fix.
            Utils.CheckISymbols(info.CandidateSymbols,
                "void C.Test(float f)");
        }
 
        [WorkItem(529596, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529596")]
        [Fact(Skip = "529596")]
        public void DelegateFromValueTypeExtensionMethod()
        {
            var source = @"
public delegate void VoidDelegate();
 
static class C
{
    public static void Goo(this int x)
    {
        VoidDelegate v;
        v = x.Goo; // CS1113
        v = new VoidDelegate(x.Goo); // Roslyn reports CS0123
        v += x.Goo; // Roslyn reports CS0019
    }
}
";
            // TODO: Dev10 reports CS1113 for all of these.  Roslyn reports various other diagnostics
            // because we detect the condition for CS1113 and then indicate that no conversion exists,
            // resulting in various cascaded errors.
            CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics(
                // (9,13): error CS1113: Extension method 'C.Goo(int)' defined on value type 'int' cannot be used to create delegates
                Diagnostic(ErrorCode.ERR_ValueTypeExtDelegate, "x.Goo").WithArguments("C.Goo(int)", "int").WithLocation(9, 13),
                // (10,13): error CS1113: Extension method 'C.Goo(int)' defined on value type 'int' cannot be used to create delegates
                Diagnostic(ErrorCode.ERR_ValueTypeExtDelegate, "new VoidDelegate(x.Goo)").WithArguments("C.Goo(int)", "int").WithLocation(10, 13),
                // (11,14): error CS1113: Extension method 'C.Goo(int)' defined on value type 'int' cannot be used to create delegates
                Diagnostic(ErrorCode.ERR_ValueTypeExtDelegate, "x.Goo").WithArguments("'C.Goo(int)", "int").WithLocation(11, 14));
        }
 
        [Fact]
        public void DelegateFromGenericExtensionMethod()
        {
            var source = @"
public delegate void VoidDelegate();
 
static class DevDivBugs142219
{
    public static void Goo<T>(this T x)
    {
        VoidDelegate f = x.Goo; // CS1113
    }
    public static void Bar<T>(this T x) where T : class
    {
        VoidDelegate f = x.Bar; // ok
    }
}
";
            CreateCompilationWithMscorlib40AndSystemCore(source).VerifyDiagnostics(
                // (8,26): error CS1113: Extension method 'DevDivBugs142219.Goo<T>(T)' defined on value type 'T' cannot be used to create delegates
                //         VoidDelegate f = x.Goo; // CS1113
                Diagnostic(ErrorCode.ERR_ValueTypeExtDelegate, "x.Goo").WithArguments("DevDivBugs142219.Goo<T>(T)", "T"));
        }
 
        [ClrOnlyFact]
        [WorkItem(545734, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545734")]
        public void ExtensionMethodWithRefParameterFromMetadata()
        {
            var lib = @"
public static class Extensions
{
        public static bool TryGetWithoutAttributeSuffix(
            this string name,
            out string result)
        {
            result = ""42"";
            return false;
        }
}";
            var consumer = @"
static class Program
{
    static void Main()
    {
        var symbolName = ""test"";
        string nameWithoutAttributeSuffix;
        symbolName.TryGetWithoutAttributeSuffix(out nameWithoutAttributeSuffix);
    }
}";
            var libCompilation = CreateCompilationWithMscorlib40AndSystemCore(lib, assemblyName: Guid.NewGuid().ToString());
            var libReference = new CSharpCompilationReference(libCompilation);
 
            CompileAndVerify(consumer, references: new[] { libReference });
        }
 
        [Fact, WorkItem(545800, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545800")]
        public void SameExtensionMethodSymbol()
        {
            var src1 = @"
using System.Collections.Generic;
 
public class MyClass
{
    public void InstanceMethod<T>(T t)  {    }
}
 
public static class Extensions
{
    public static void ExtensionMethod<T>(this MyClass p, T t)  {    }
}
 
class Test
{
    static void Main()
    {
        var obj = new MyClass();
        obj.InstanceMethod('q');
        obj.ExtensionMethod('c');
    }
}
";
 
            var comp = CreateCompilation(src1);
            var tree = comp.SyntaxTrees[0];
            var model = comp.GetSemanticModel(tree);
 
            var nodes = tree.GetCompilationUnitRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().ToList();
            Assert.Equal(2, nodes.Count);
 
            var firstInvocation = nodes[0];
            var firstInvocationExpression = firstInvocation.Expression;
            var firstInvocationSymbol = model.GetSymbolInfo(firstInvocation).Symbol;
            var firstInvocationExpressionSymbol = model.GetSymbolInfo(firstInvocationExpression).Symbol;
 
            var secondInvocation = nodes[1];
            var secondInvocationExpression = secondInvocation.Expression;
            var secondInvocationSymbol = model.GetSymbolInfo(secondInvocation).Symbol;
            var secondInvocationExpressionSymbol = model.GetSymbolInfo(secondInvocationExpression).Symbol;
 
            Assert.Equal("obj.InstanceMethod", firstInvocationExpression.ToString());
            Assert.Equal(SyntaxKind.SimpleMemberAccessExpression, firstInvocationExpression.Kind());
            Assert.Equal(SymbolKind.Method, firstInvocationSymbol.Kind);
            Assert.Equal("InstanceMethod", firstInvocationSymbol.Name);
            Assert.Equal(firstInvocationSymbol, firstInvocationExpressionSymbol);
 
            Assert.Equal("obj.ExtensionMethod", secondInvocationExpression.ToString());
            Assert.Equal(SyntaxKind.SimpleMemberAccessExpression, secondInvocationExpression.Kind());
            Assert.Equal(SymbolKind.Method, secondInvocationSymbol.Kind);
            Assert.Equal("ExtensionMethod", secondInvocationSymbol.Name);
            Assert.Equal(secondInvocationSymbol, secondInvocationExpressionSymbol);
        }
 
        /// <summary>
        /// Dev11 allows referencing extension methods defined on
        /// non-static classes, generic classes, structs, and delegates.
        /// </summary>
        [WorkItem(546093, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546093")]
        [Fact]
        public void NonStaticClasses()
        {
            var source1 =
@".assembly extern mscorlib { .ver 4:0:0:0 .publickeytoken = (B7 7A 5C 56 19 34 E0 89) }
.assembly extern System.Core {}
.assembly '<<GeneratedFileName>>'
{
    .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
}
.class public A
{
  .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
  .method public hidebysig specialname rtspecialname instance void .ctor() { ret }
  // public method
  .method public static void MA(object o)
  {
    .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
    ret
  }
  // protected method
  .method family static void MP(object o)
  {
    .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
    ret
  }
}
.class public B<T>
{
  .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
  .method public hidebysig specialname rtspecialname instance void .ctor() { ret }
  // generic type method
  .method public static void MB(object o)
  {
    .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
    ret
  }
}
.class public sealed S extends [mscorlib]System.ValueType
{
  .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
  // struct method
  .method public static void MS(object o)
  {
    .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
    ret
  }
}
.class public abstract interface I
{
  .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
  // interface method
  .method public static void MI(object o)
  {
    .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
    ret
  }
}
.class public sealed D extends [mscorlib]System.MulticastDelegate
{
  .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
  .method public instance void Invoke() { ret }
  // delegate method
  .method public static void MD(object o)
  {
    .custom instance void [System.Core]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 )
    ret
  }
}";
            var reference1 = CompileIL(source1, prependDefaultHeader: false);
            var source2 =
@"class C : A
{
    static void M(object o)
    {
        o.MA(); // A.MA()
        o.MP(); // A.MP() (protected)
        o.MB(); // B<T>.MB()
        o.MS(); // S.MS()
        o.MI(); // I.MI()
        o.MD(); // D.MD()
    }
}";
            var compilation = CreateCompilation(source2, new[] { reference1 });
            compilation.VerifyDiagnostics(
                // (9,11): error CS1061: 'object' does not contain a definition for 'MI' and no extension method 'MI' accepting a first argument of type 'object' could be found (are you missing a using directive or an assembly reference?)
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "MI").WithArguments("object", "MI").WithLocation(9, 11));
        }
 
        [WorkItem(546093, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546093")]
        [ClrOnlyFact]
        public void VBExtensionMethod()
        {
            var source1 =
@"Imports System.Runtime.CompilerServices
Public Module M
    <Extension()>
    Public Sub F(o As Object)
    End Sub
End Module";
            var reference1 = BasicCompilationUtils.CompileToMetadata(source1, references: new[] { MscorlibRef, SystemCoreRef, MsvbRef });
            var source2 =
@"class C
{
    static void M(object o)
    {
        o.F();
    }
}";
            var compilation2 = CreateCompilation(source2, new[] { reference1 });
            compilation2.VerifyDiagnostics();
        }
 
        [WorkItem(602893, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/602893")]
        [ClrOnlyFact]
        public void Bug602893()
        {
            var source1 =
@"namespace NA
{
    internal static class A
    {
        public static void F(this object o) { }
    }
}";
            var compilation1 = CreateCompilationWithMscorlib40AndSystemCore(source1, assemblyName: "A");
            compilation1.VerifyDiagnostics();
            var compilationVerifier = CompileAndVerify(compilation1);
            var reference1 = MetadataReference.CreateFromImage(compilationVerifier.EmittedAssemblyData);
            var source2 =
@"[assembly: System.Runtime.CompilerServices.InternalsVisibleTo(""C"")]
namespace NB
{
    internal static class B
    {
        public static void F(this object o) { }
    }
}";
            var compilation2 = CreateCompilationWithMscorlib40AndSystemCore(source2, assemblyName: "B");
            compilation2.VerifyDiagnostics();
            compilationVerifier = CompileAndVerify(compilation2);
            var reference2 = MetadataReference.CreateFromImage(compilationVerifier.EmittedAssemblyData);
            var source3 =
@"using NB;
namespace NA.NC
{
    class C
    {
        static void Main()
        {
            new object().F();
        }
    }
}";
            var compilation3 = CreateCompilation(source3, assemblyName: "C", references: new[] { reference1, reference2 });
            compilation3.VerifyDiagnostics();
        }
 
        /// <summary>
        /// As test above but with all classes defined in the same compilation.
        /// </summary>
        [WorkItem(602893, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/602893")]
        [Fact]
        public void Bug602893_2()
        {
            var source =
@"using NB;
namespace NA
{
    internal static class A
    {
        static void F(this object o) { }
    }
}
namespace NB
{
    internal static class B
    {
        public static void F(this object o) { }
    }
}
namespace NA
{
    class C
    {
        static void Main()
        {
            new object().F();
        }
    }
}";
            var compilation = CreateCompilationWithMscorlib40AndSystemCore(source);
            compilation.VerifyDiagnostics();
        }
 
        /// <summary>
        /// Ambiguous methods should hide methods in outer scopes.
        /// </summary>
        [Fact]
        public void AmbiguousMethodsHideOuterScope()
        {
            var source =
@"using NB;
namespace NA
{
    internal static class A
    {
        public static void F(this object o) { }
    }
    internal static class B
    {
        public static void F(this object o) { }
    }
    class C
    {
        static void Main()
        {
            new object().F();
        }
    }
}
namespace NB
{
    internal static class B
    {
        public static void F(this object o) { }
    }
}";
            var compilation = CreateCompilationWithMscorlib40AndSystemCore(source);
            compilation.VerifyDiagnostics(
                // (16,13): error CS0121: The call is ambiguous between the following methods or properties: 'NA.A.F(object)' and 'NA.B.F(object)'
                Diagnostic(ErrorCode.ERR_AmbigCall, "F").WithArguments("NA.A.F(object)", "NA.B.F(object)").WithLocation(16, 26),
                // (1,1): info CS8019: Unnecessary using directive.
                // using NB;
                Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using NB;"));
        }
 
        [Fact, WorkItem(822125, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/822125")]
        public void ConsumeFSharpExtensionMethods()
        {
            var source =
@"using FSharpTestLibrary;
 
namespace CSharpApp
{
    class Program
    {
        static void Main()
        {
            var question = 42.GetQuestion();
        }
    }
}";
            var compilation = CreateCompilation(source, references: new[] { FSharpTestLibraryRef });
            compilation.VerifyDiagnostics();
        }
 
        [ClrOnlyFact]
        public void InternalExtensionAttribute()
        {
            var source =
@"
namespace System.Runtime.CompilerServices
{
    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
    class ExtensionAttribute : Attribute
    {
    }
}
 
internal static class Test
{
    public static void M(this int p)
    {
    }
}
";
            var compilation = CreateEmptyCompilation(source, new[] { MscorlibRef_v20 }, TestOptions.ReleaseDll);
            CompileAndVerify(compilation);
        }
 
        [ClrOnlyFact]
        [WorkItem(1010648, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1010648")]
        public void ExtensionMethodFromUsingStatic()
        {
            const string source = @"
using System;
using static N.S;
 
class Program
{
    static void Main()
    {
        1.Goo();
    }
}
 
namespace N
{
    static class S
    {
        public static void Goo(this int x)
        {
            Console.Write(x);
        }
    }
}";
            CompileAndVerify(source, expectedOutput: "1");
        }
 
        [Fact, WorkItem(1085744, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1085744")]
        public void ExtensionMethodsAreNotImportedAsSimpleNames()
        {
            const string source = @"
using System;
using static N.S;
 
class Program
{
    static void Main()
    {
        1.Goo();
        Goo(1);
    }
}
 
namespace N
{
    static class S
    {
        public static void Goo(this int x)
        {
            Console.Write(x);
        }
    }
}";
            var compilation = CreateCompilationWithMscorlib40AndSystemCore(source);
            compilation.VerifyDiagnostics(
                // (10,9): error CS0103: The name 'Goo' does not exist in the current context
                //         Goo(1);
                Diagnostic(ErrorCode.ERR_NameNotInContext, "Goo").WithArguments("Goo").WithLocation(10, 9));
        }
 
        [ClrOnlyFact]
        [WorkItem(1010648, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1010648")]
        public void ExtensionMethodImportedTwiceNoErrors()
        {
            const string source = @"
using System;
using N;
using static N.S;
 
class Program
{
    static void Main()
    {
        1.Goo();
    }
}
 
namespace N
{
    static class S
    {
        public static void Goo(this int x)
        {
            Console.WriteLine(x);
        }
    }
}";
            CompileAndVerify(source, expectedOutput: "1");
        }
 
        [Fact, WorkItem(1010648, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1010648")]
        public void ExtensionMethodIsNotDisambiguatedByUsingStaticAtTheSameLevel()
        {
            const string source = @"
using N;
using static N.S;
 
class Program
{
    static void Main()
    {
        1.Goo();
    }
}
 
namespace N
{
    static class S
    {
        public static void Goo(this int x)
        {
        }
    }
 
    static class R
    {
        public static void Goo(this int x)
        {
        }
    }
}";
            var compilation = CreateCompilationWithMscorlib40AndSystemCore(source);
            compilation.VerifyDiagnostics(
                // (9,11): error CS0121: The call is ambiguous between the following methods or properties: 'S.Goo(int)' and 'R.Goo(int)'
                //         1.Goo();
                Diagnostic(ErrorCode.ERR_AmbigCall, "Goo").WithArguments("N.S.Goo(int)", "N.R.Goo(int)").WithLocation(9, 11));
        }
 
        [ClrOnlyFact]
        [WorkItem(1010648, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1010648")]
        public void ExtensionMethodIsDisambiguatedByUsingStaticAtDeeperLevel()
        {
            const string source = @"
using System;
using N;
 
namespace K
{
    using static S;
 
    class Program
    {
        static void Main()
        {
            1.Goo();
        }
    }
}
 
namespace N
{
    static class S
    {
        public static void Goo(this int x)
        {
            Console.WriteLine(""S"");
        }
    }
 
    static class R
    {
        public static void Goo(this int x)
        {
            Console.WriteLine(""R"");
        }
    }
}";
            CompileAndVerify(source, expectedOutput: "S");
        }
 
        [Fact, WorkItem(1010648, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1010648")]
        public void ExtensionMethodAmbiguousAcrossMultipleUsingStatic()
        {
            const string source = @"
using System;
 
namespace K
{
    using static N.S;
    using static N.R;
 
    class Program
    {
        static void Main()
        {
            1.Goo();
        }
    }
}
 
namespace N
{
    static class S
    {
        public static void Goo(this int x)
        {
            Console.WriteLine(""S"");
        }
    }
 
    static class R
    {
        public static void Goo(this int x)
        {
            Console.WriteLine(""R"");
        }
    }
}";
            var compilation = CreateCompilationWithMscorlib40AndSystemCore(source);
            compilation.VerifyDiagnostics(
                // (13,15): error CS0121: The call is ambiguous between the following methods or properties: 'S.Goo(int)' and 'R.Goo(int)'
                //             1.Goo();
                Diagnostic(ErrorCode.ERR_AmbigCall, "Goo").WithArguments("N.S.Goo(int)", "N.R.Goo(int)").WithLocation(13, 15));
        }
 
        [Fact, WorkItem(1010648, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1010648")]
        public void ExtensionMethodsInTheContainingClassDoNotHaveHigherPrecedence()
        {
            const string source = @"
namespace N
{
    using static Program;
 
    static class Program
    {
        static void Main()
        {
            1.Goo();
        }
 
        public static void Goo(this int x)
        {
        }
    }
 
    static class R
    {
        public static void Goo(this int x)
        {
        }
    }
}";
            var compilation = CreateCompilationWithMscorlib40AndSystemCore(source);
            compilation.VerifyDiagnostics(
                // (10,15): error CS0121: The call is ambiguous between the following methods or properties: 'Program.Goo(int)' and 'R.Goo(int)'
                //             1.Goo();
                Diagnostic(ErrorCode.ERR_AmbigCall, "Goo").WithArguments("N.Program.Goo(int)", "N.R.Goo(int)").WithLocation(10, 15),
                // (4,5): hidden CS8019: Unnecessary using directive.
                //     using Program;
                Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using static Program;").WithLocation(4, 5));
        }
 
        [Fact, WorkItem(1010648, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1010648")]
        public void UsingAliasDoesNotImportExtensionMethods()
        {
            const string source = @"
namespace K
{
    using X = N.S;
    class Program
    {
        static void Main()
        {
            1.Goo();
        }
    }
}
 
namespace N
{
    static class S
    {
        public static void Goo(this int x)
        {
        }
    }
}";
            var compilation = CreateCompilationWithMscorlib40AndSystemCore(source);
            compilation.VerifyDiagnostics(
                // (9,15): error CS1061: 'int' does not contain a definition for 'Goo' and no extension method 'Goo' accepting a first argument of type 'int' could be found (are you missing a using directive or an assembly reference?)
                //             1.Goo();
                Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "Goo").WithArguments("int", "Goo").WithLocation(9, 15),
                // (4,5): hidden CS8019: Unnecessary using directive.
                //     using X = N.S;
                Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using X = N.S;").WithLocation(4, 5));
        }
 
        [WorkItem(1094849, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1094849"), WorkItem(2288, "https://github.com/dotnet/roslyn/issues/2288")]
        [Fact]
        public void LookupSymbolsWithPartialInference()
        {
            var source =
@"
using System.Collections.Generic;
 
namespace ConsoleApplication22
{
    static class Program
    {
        static void Main(string[] args)
        {
        }
 
        internal static void GetEnumerableDisposable1<T, TEnumerator>(this IEnumerable<T> enumerable)
            where TEnumerator : struct , IEnumerator<T>
        {
        }
 
        internal static void GetEnumerableDisposable2<T, TEnumerator>(this IEnumerable<T> enumerable)
            where TEnumerator : struct
        {
        }
 
        private static void Overlaps<T, TEnumerator>(IEnumerable<T> other) where TEnumerator : struct, IEnumerator<T>
        {
            other.GetEnumerableDisposable1<T, TEnumerator>();
        }
    }
}";
            var compilation = CreateCompilation(source);
 
            compilation.VerifyDiagnostics();
            var syntaxTree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(syntaxTree);
 
            var member = (MemberAccessExpressionSyntax)syntaxTree.GetRoot().DescendantNodes().OfType<InvocationExpressionSyntax>().Single().Expression;
            Assert.Equal("other.GetEnumerableDisposable1<T, TEnumerator>", member.ToString());
 
            var type = model.GetTypeInfo(member.Expression).Type;
            Assert.Equal("System.Collections.Generic.IEnumerable<T>", type.ToTestDisplayString());
 
            var symbols = model.LookupSymbols(member.Expression.EndPosition, type, includeReducedExtensionMethods: true).Select(s => s.Name).ToArray();
            Assert.Contains("GetEnumerableDisposable2", symbols);
            Assert.Contains("GetEnumerableDisposable1", symbols);
        }
 
        [Fact]
        public void ScriptExtensionMethods()
        {
            var source =
@"static object F(this object o) { return null; }
class C
{
    void M() { this.F(); }
}
var o = new object();
o.F();";
            var compilation = CreateCompilationWithMscorlib461(source, parseOptions: TestOptions.Script);
            compilation.VerifyDiagnostics();
        }
 
        [Fact]
        public void InteractiveExtensionMethods()
        {
            var parseOptions = TestOptions.Script;
            var references = new[] { MscorlibRef, SystemCoreRef };
            var source0 =
@"static object F(this object o) { return 0; }
var o = new object();
o.F();";
            var source1 =
@"static object G(this object o) { return 1; }
var o = new object();
o.G().F();";
 
            var s0 = CSharpCompilation.CreateScriptCompilation(
                "s0.dll",
                syntaxTree: SyntaxFactory.ParseSyntaxTree(source0, options: parseOptions),
                references: references);
            s0.VerifyDiagnostics();
 
            var s1 = CSharpCompilation.CreateScriptCompilation(
                "s1.dll",
                syntaxTree: SyntaxFactory.ParseSyntaxTree(source1, options: parseOptions),
                previousScriptCompilation: s0,
                references: references);
            s1.VerifyDiagnostics();
        }
 
        [Fact]
        [WorkItem(11166, "https://github.com/dotnet/roslyn/issues/11166")]
        public void SemanticModelLookup_01()
        {
            var source =
@"
public static class TestClass 
{
    public static void Test() 
    {
        var Instance = new BaseClass<int>();
        Instance.SetMember(32);
    }
}
 
public static class Extensions
{
    public static BC SetMember<BC, TMember>(this BC This, TMember NewValue) where BC : BaseClass<TMember> {
        This.Member = NewValue;
        return This;
    }
}
 
public class BaseClass<TMember>
{
    public TMember Member { get; set; }
}
";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics();
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var instance = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(n => n.Identifier.ValueText == "Instance").First();
            Assert.Equal("Instance.SetMember", instance.Parent.ToString());
            var baseClass = model.GetTypeInfo(instance).Type;
            Assert.Equal("BaseClass<System.Int32>", baseClass.ToTestDisplayString());
 
            var setMember = model.LookupSymbols(instance.Position, baseClass, "SetMember", includeReducedExtensionMethods: true).Single();
            Assert.Equal("BaseClass<System.Int32> BaseClass<System.Int32>.SetMember<BaseClass<System.Int32>, TMember>(TMember NewValue)", setMember.ToTestDisplayString());
            Assert.Contains(setMember, model.LookupSymbols(instance.Position, baseClass, includeReducedExtensionMethods: true));
        }
 
        [Fact]
        [WorkItem(11166, "https://github.com/dotnet/roslyn/issues/11166")]
        public void SemanticModelLookup_02()
        {
            var source =
@"
public static class TestClass 
{
    public static void Test() 
    {
        var Instance = new BaseClass<int>();
        Instance.SetMember(32);
    }
}
 
public static class Extensions
{
    public static BC SetMember<BC, TMember>(this BC This, TMember NewValue) where BC : BaseClass<long> {
        return This;
    }
}
 
public class BaseClass<TMember>
{
    public TMember Member { get; set; }
}
";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (7,18): error CS0311: The type 'BaseClass<int>' cannot be used as type parameter 'BC' in the generic type or method 'Extensions.SetMember<BC, TMember>(BC, TMember)'. There is no implicit reference conversion from 'BaseClass<int>' to 'BaseClass<long>'.
                //         Instance.SetMember(32);
                Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedRefType, "SetMember").WithArguments("Extensions.SetMember<BC, TMember>(BC, TMember)", "BaseClass<long>", "BC", "BaseClass<int>").WithLocation(7, 18)
                );
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var instance = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(n => n.Identifier.ValueText == "Instance").First();
            Assert.Equal("Instance.SetMember", instance.Parent.ToString());
            var baseClass = model.GetTypeInfo(instance).Type;
            Assert.Equal("BaseClass<System.Int32>", baseClass.ToTestDisplayString());
 
            Assert.Empty(model.LookupSymbols(instance.Position, baseClass, "SetMember", includeReducedExtensionMethods: true));
            Assert.Empty(model.LookupSymbols(instance.Position, baseClass, includeReducedExtensionMethods: true).Where(s => s.Name == "SetMembers"));
        }
 
        [Fact]
        [WorkItem(11166, "https://github.com/dotnet/roslyn/issues/11166")]
        public void SemanticModelLookup_03()
        {
            var source =
@"
public static class TestClass 
{
    public static void Test() 
    {
        var Instance = new BaseClass<int>();
        Instance.SetMember(32);
    }
}
 
public static class Extensions
{
    public static BC SetMember<BC, TMember>(this BC This, TMember NewValue) where BC : BaseClass<TMember>, I1<TMember> {
        This.Member = NewValue;
        return This;
    }
}
 
public interface I1<T>{}
 
public class BaseClass<TMember> : I1<TMember>
{
    public TMember Member { get; set; }
}
";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics();
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var instance = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(n => n.Identifier.ValueText == "Instance").First();
            Assert.Equal("Instance.SetMember", instance.Parent.ToString());
            var baseClass = model.GetTypeInfo(instance).Type;
            Assert.Equal("BaseClass<System.Int32>", baseClass.ToTestDisplayString());
 
            var setMember = model.LookupSymbols(instance.Position, baseClass, "SetMember", includeReducedExtensionMethods: true).Single();
            Assert.Equal("BaseClass<System.Int32> BaseClass<System.Int32>.SetMember<BaseClass<System.Int32>, TMember>(TMember NewValue)", setMember.ToTestDisplayString());
            Assert.Contains(setMember, model.LookupSymbols(instance.Position, baseClass, includeReducedExtensionMethods: true));
        }
 
        [Fact]
        [WorkItem(11166, "https://github.com/dotnet/roslyn/issues/11166")]
        public void SemanticModelLookup_04()
        {
            var source =
@"
public static class TestClass 
{
    public static void Test() 
    {
        var Instance = new BaseClass<int>();
        Instance.SetMember(32);
    }
}
 
public static class Extensions
{
    public static BC SetMember<BC, TMember>(this BC This, TMember NewValue) where BC : BaseClass<TMember>, I1<long> {
        This.Member = NewValue;
        return This;
    }
}
 
public interface I1<T>{}
 
public class BaseClass<TMember> : I1<TMember>
{
    public TMember Member { get; set; }
}
";
            var compilation = CreateCompilation(source);
            compilation.VerifyDiagnostics(
                // (7,18): error CS0311: The type 'BaseClass<int>' cannot be used as type parameter 'BC' in the generic type or method 'Extensions.SetMember<BC, TMember>(BC, TMember)'. There is no implicit reference conversion from 'BaseClass<int>' to 'I1<long>'.
                //         Instance.SetMember(32);
                Diagnostic(ErrorCode.ERR_GenericConstraintNotSatisfiedRefType, "SetMember").WithArguments("Extensions.SetMember<BC, TMember>(BC, TMember)", "I1<long>", "BC", "BaseClass<int>").WithLocation(7, 18)
                );
 
            var tree = compilation.SyntaxTrees.Single();
            var model = compilation.GetSemanticModel(tree);
 
            var instance = tree.GetRoot().DescendantNodes().OfType<IdentifierNameSyntax>().Where(n => n.Identifier.ValueText == "Instance").First();
            Assert.Equal("Instance.SetMember", instance.Parent.ToString());
            var baseClass = model.GetTypeInfo(instance).Type;
            Assert.Equal("BaseClass<System.Int32>", baseClass.ToTestDisplayString());
 
            Assert.Empty(model.LookupSymbols(instance.Position, baseClass, "SetMember", includeReducedExtensionMethods: true));
            Assert.Empty(model.LookupSymbols(instance.Position, baseClass, includeReducedExtensionMethods: true).Where(s => s.Name == "SetMembers"));
        }
 
        [Fact]
        public void InExtensionMethods()
        {
            var source = @"
public static class C
{
    public static void M1(this in int p) { }
    public static void M2(in this int p) { }
}";
 
            void validator(ModuleSymbol module)
            {
                var type = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
 
                var method = type.GetMember<MethodSymbol>("M1");
                Assert.True(method.IsExtensionMethod);
                var parameter = method.Parameters[0];
                Assert.Equal(SpecialType.System_Int32, parameter.Type.SpecialType);
                Assert.Equal(RefKind.In, parameter.RefKind);
 
                method = type.GetMember<MethodSymbol>("M2");
                Assert.True(method.IsExtensionMethod);
                parameter = method.Parameters[0];
                Assert.Equal(SpecialType.System_Int32, parameter.Type.SpecialType);
                Assert.Equal(RefKind.In, parameter.RefKind);
            }
 
            CompileAndVerify(source, validator: validator, options: TestOptions.ReleaseDll);
        }
 
        [Fact]
        public void RefExtensionMethods()
        {
            var source = @"
public static class C
{
    public static void M1(this ref int p) { }
    public static void M2(ref this int p) { }
}";
 
            void validator(ModuleSymbol module)
            {
                var type = module.GlobalNamespace.GetMember<NamedTypeSymbol>("C");
 
                var method = type.GetMember<MethodSymbol>("M1");
                Assert.True(method.IsExtensionMethod);
                var parameter = method.Parameters[0];
                Assert.Equal(SpecialType.System_Int32, parameter.Type.SpecialType);
                Assert.Equal(RefKind.Ref, parameter.RefKind);
 
                method = type.GetMember<MethodSymbol>("M2");
                Assert.True(method.IsExtensionMethod);
                parameter = method.Parameters[0];
                Assert.Equal(SpecialType.System_Int32, parameter.Type.SpecialType);
                Assert.Equal(RefKind.Ref, parameter.RefKind);
            }
 
            CompileAndVerify(source, validator: validator, options: TestOptions.ReleaseDll);
        }
 
        [Fact]
        [WorkItem(65020, "https://github.com/dotnet/roslyn/issues/65020")]
        public void ReduceExtensionsMethodOnReceiverTypeSystemVoid()
        {
            var source =
@"static class C
{
    static void M(this object x)
    {
    }
}";
            var compilation = CreateCompilationWithMscorlib40AndSystemCore(source);
            compilation.VerifyDiagnostics();
 
            var extensionMethod = compilation.GlobalNamespace.GetMember<NamedTypeSymbol>("C").GetMember<MethodSymbol>("M");
            Assert.True(extensionMethod.IsExtensionMethod);
 
            var systemVoidType = compilation.GetSpecialType(SpecialType.System_Void);
            Assert.Equal(SpecialType.System_Void, systemVoidType.SpecialType);
 
            var reduced = extensionMethod.ReduceExtensionMethod(systemVoidType, null!);
            Assert.Null(reduced);
 
            reduced = extensionMethod.ReduceExtensionMethod(systemVoidType, compilation);
            Assert.Null(reduced);
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/68110")]
        public void DefaultSyntaxValueReentrancy_01()
        {
            var source =
                """
                #nullable enable
 
                [A(3, X = 6)]
                public struct A
                {
                    public int X;
 
                    public A(int x, A a = new A().M(1)) { }
                }
 
                public static class AExt
                {
                    public static void M(this A s, ref int i) {}
                }
                """;
            var compilation = CreateCompilation(source, targetFramework: TargetFramework.NetCoreApp);
 
            var a = compilation.GlobalNamespace.GetTypeMember("A").InstanceConstructors.Where(c => !c.IsDefaultValueTypeConstructor()).Single();
 
            Assert.Null(a.Parameters[1].ExplicitDefaultValue);
            Assert.True(a.Parameters[1].HasExplicitDefaultValue);
 
            compilation.VerifyDiagnostics(
                // (3,2): error CS0616: 'A' is not an attribute class
                // [A(3, X = 6)]
                Diagnostic(ErrorCode.ERR_NotAnAttributeClass, "A").WithArguments("A").WithLocation(3, 2),
                // (3,2): error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type
                // [A(3, X = 6)]
                Diagnostic(ErrorCode.ERR_BadAttributeArgument, "A(3, X = 6)").WithLocation(3, 2),
                // (8,37): error CS1620: Argument 2 must be passed with the 'ref' keyword
                //     public A(int x, A a = new A().M(1)) { }
                Diagnostic(ErrorCode.ERR_BadArgRef, "1").WithArguments("2", "ref").WithLocation(8, 37));
        }
 
        [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74404")]
        public void Repro_74404()
        {
            var source = """
                #nullable enable
                class C<T>;
                static class CExt
                {
                    public static void M<T>(this C<T> c)
                    {
                        c.M = 42;
                    }
                }
                """;
            var comp = CreateCompilation(source);
            comp.VerifyEmitDiagnostics(
                // (7,9): error CS1656: Cannot assign to 'M' because it is a 'method group'
                //         c.M = 42;
                Diagnostic(ErrorCode.ERR_AssgReadonlyLocalCause, "c.M").WithArguments("M", "method group").WithLocation(7, 9));
        }
    }
}