[mcs] Improve extension methods error reporting
authorMarek Safar <marek.safar@gmail.com>
Wed, 3 Dec 2014 17:31:35 +0000 (18:31 +0100)
committerMarek Safar <marek.safar@gmail.com>
Wed, 3 Dec 2014 21:02:22 +0000 (22:02 +0100)
15 files changed:
mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/RuntimeBinderContext.cs
mcs/errors/cs1061-17.cs [new file with mode: 0644]
mcs/errors/cs1928-2.cs [deleted file]
mcs/errors/cs1928-3.cs [deleted file]
mcs/errors/cs1929-2.cs [new file with mode: 0644]
mcs/errors/cs1929-3.cs [new file with mode: 0644]
mcs/errors/cs1929.cs
mcs/mcs/class.cs
mcs/mcs/context.cs
mcs/mcs/decl.cs
mcs/mcs/doc.cs
mcs/mcs/ecore.cs
mcs/mcs/expression.cs
mcs/mcs/namespace.cs
mcs/mcs/pending.cs

index bcb6e3c0b0e43044d7ab974d8915d3a5c8b10c7c..e2b38dbfcd673f5d19ea9346f4a820fb232f1a1a 100644 (file)
@@ -111,7 +111,7 @@ namespace Microsoft.CSharp.RuntimeBinder
                        throw new NotImplementedException ();
                }
 
-               public Compiler.ExtensionMethodCandidates LookupExtensionMethod (Compiler.TypeSpec extensionType, string name, int arity)
+               public Compiler.ExtensionMethodCandidates LookupExtensionMethod (string name, int arity)
                {
                        // No extension method lookup in this context
                        return null;
diff --git a/mcs/errors/cs1061-17.cs b/mcs/errors/cs1061-17.cs
new file mode 100644 (file)
index 0000000..1e17496
--- /dev/null
@@ -0,0 +1,17 @@
+// CS1061: Type `int' does not contain a definition for `Foo' and no extension method `Foo' of type `int' could be found. Are you missing an assembly reference?
+// Line: 11
+
+using System;
+
+static class C
+{
+       static void Main ()
+       {
+               int i = 1;
+               Action a = i.Foo;
+       }
+
+       static void Foo (this string s)
+       {
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1928-2.cs b/mcs/errors/cs1928-2.cs
deleted file mode 100644 (file)
index f5cefeb..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// CS1928: Type `System.Collections.IList' does not contain a member `Frobnicate' and the best extension method overload `Extensions.Frobnicate<Test>(this Test)' has some invalid arguments
-// Line: 20
-
-using System;
-using System.Collections;
-
-static class Extensions
-{
-       public static void Frobnicate<T> (this T foo) where T : IList
-       {
-       }
-}
-
-public class Test
-{
-       IList mFoo;
-
-       void Frobnicate ()
-       {
-               mFoo.Frobnicate<Test> ();
-       }
-}
diff --git a/mcs/errors/cs1928-3.cs b/mcs/errors/cs1928-3.cs
deleted file mode 100644 (file)
index 0eee7b2..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-// CS1928: Type `int' does not contain a member `Foo' and the best extension method overload `S.Foo(this uint)' has some invalid arguments
-// Line: 15
-
-static class S
-{
-       public static void Foo (this uint i)
-       {
-       }
-}
-
-class B
-{
-       static void Main ()
-       {
-               55.Foo ();
-       }
-}
diff --git a/mcs/errors/cs1929-2.cs b/mcs/errors/cs1929-2.cs
new file mode 100644 (file)
index 0000000..9982fef
--- /dev/null
@@ -0,0 +1,22 @@
+// CS1929: Type `System.Collections.IList' does not contain a member `Frobnicate' and the best extension method overload `Extensions.Frobnicate<Test>(this Test)' requires an instance of type `Test'
+// Line: 20
+
+using System;
+using System.Collections;
+
+static class Extensions
+{
+       public static void Frobnicate<T> (this T foo) where T : IList
+       {
+       }
+}
+
+public class Test
+{
+       IList mFoo;
+
+       void Frobnicate ()
+       {
+               mFoo.Frobnicate<Test> ();
+       }
+}
diff --git a/mcs/errors/cs1929-3.cs b/mcs/errors/cs1929-3.cs
new file mode 100644 (file)
index 0000000..c385ca8
--- /dev/null
@@ -0,0 +1,17 @@
+// CS1929: Type `int' does not contain a member `Foo' and the best extension method overload `S.Foo(this uint)' requires an instance of type `uint'
+// Line: 15
+
+static class S
+{
+       public static void Foo (this uint i)
+       {
+       }
+}
+
+class B
+{
+       static void Main ()
+       {
+               55.Foo ();
+       }
+}
index 6358f368f434bdce6108107f107379cfe9795aa8..4679492a1fe59334fbf36671d34b2d0d0ca6aa02 100644 (file)
@@ -1,4 +1,4 @@
-// CS1929: Extension method instance type `int' cannot be converted to `string'
+// CS1929: Type `int' does not contain a member `Check' and the best extension method overload `C.Check(this string)' requires an instance of type `string'
 // Line: 12
 
 static class C
index 5dac7c44002dad96b133628063cb42ce2bb7edb4..9c841a2140fadfae8c2b9bb4665d818590b08063 100644 (file)
@@ -452,7 +452,7 @@ namespace Mono.CSharp
                                return tc.GetSignatureForError ();
                        }
 
-                       public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
+                       public ExtensionMethodCandidates LookupExtensionMethod (string name, int arity)
                        {
                                return null;
                        }
index e2bcbe61660be08f50b33b35c991392d20140313..88e523700706480b073713dc308dcdc7b8a31625 100644 (file)
@@ -55,7 +55,7 @@ namespace Mono.CSharp
 
                string GetSignatureForError ();
 
-               ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity);
+               ExtensionMethodCandidates LookupExtensionMethod (string name, int arity);
                FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc);
                FullNamedExpression LookupNamespaceAlias (string name);
        }
@@ -424,9 +424,9 @@ namespace Mono.CSharp
                        return MemberContext.GetSignatureForError ();
                }
 
-               public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
+               public ExtensionMethodCandidates LookupExtensionMethod (string name, int arity)
                {
-                       return MemberContext.LookupExtensionMethod (extensionType, name, arity);
+                       return MemberContext.LookupExtensionMethod (name, arity);
                }
 
                public FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
index 99476d291c7b671047ac0329a843ce900327812b..16f8bcb38360495b313d3f6b1c3a3ea7583f2d0c 100644 (file)
@@ -670,13 +670,13 @@ namespace Mono.CSharp {
                // Does extension methods look up to find a method which matches name and extensionType.
                // Search starts from this namespace and continues hierarchically up to top level.
                //
-               public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
+               public ExtensionMethodCandidates LookupExtensionMethod (string name, int arity)
                {
                        var m = Parent;
                        do {
                                var ns = m as NamespaceContainer;
                                if (ns != null)
-                                       return ns.LookupExtensionMethod (this, extensionType, name, arity, 0);
+                                       return ns.LookupExtensionMethod (this, name, arity, 0);
 
                                m = m.Parent;
                        } while (m != null);
index 35fe5852930447dcc8cbf3095a34f319638fa32e..adf6ea082d007b971c433a99e4b258aa7c0ba882 100644 (file)
@@ -695,7 +695,7 @@ namespace Mono.CSharp
                        return host.GetSignatureForError ();
                }
 
-               public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
+               public ExtensionMethodCandidates LookupExtensionMethod (string name, int arity)
                {
                        return null;
                }
index 24a79b65dfd177848489d47e2b577f1f2080992c..a02b28c9d847c1b14929aac195aea6221ef2f8e3 100644 (file)
@@ -3726,7 +3726,7 @@ namespace Mono.CSharp {
 
                        int arity = type_arguments == null ? 0 : type_arguments.Count;
 
-                       candidates = candidates.Container.LookupExtensionMethod (candidates.Context, ExtensionExpression.Type, Name, arity, candidates.LookupIndex);
+                       candidates = candidates.Container.LookupExtensionMethod (candidates.Context, Name, arity, candidates.LookupIndex);
                        if (candidates == null)
                                return null;
 
@@ -3816,14 +3816,15 @@ namespace Mono.CSharp {
                bool OverloadResolver.IErrorHandler.ArgumentMismatch (ResolveContext rc, MemberSpec best, Argument arg, int index)
                {
                        rc.Report.SymbolRelatedToPreviousError (best);
-                       rc.Report.Error (1928, loc,
-                               "Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' has some invalid arguments",
-                               queried_type.GetSignatureForError (), Name, best.GetSignatureForError ());
 
                        if (index == 0) {
                                rc.Report.Error (1929, loc,
-                                       "Extension method instance type `{0}' cannot be converted to `{1}'",
-                                       arg.Type.GetSignatureForError (), ((MethodSpec)best).Parameters.ExtensionMethodType.GetSignatureForError ());
+                                       "Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' requires an instance of type `{3}'",
+                                       queried_type.GetSignatureForError (), Name, best.GetSignatureForError (), ((MethodSpec)best).Parameters.ExtensionMethodType.GetSignatureForError ());
+                       } else {
+                               rc.Report.Error (1928, loc,
+                                       "Type `{0}' does not contain a member `{1}' and the best extension method overload `{2}' has some invalid arguments",
+                                       queried_type.GetSignatureForError (), Name, best.GetSignatureForError ());
                        }
 
                        return true;
@@ -4190,7 +4191,7 @@ namespace Mono.CSharp {
                                return null;
 
                        int arity = type_arguments == null ? 0 : type_arguments.Count;
-                       var methods = rc.LookupExtensionMethod (InstanceExpression.Type, Methods[0].Name, arity);
+                       var methods = rc.LookupExtensionMethod (Methods[0].Name, arity);
                        if (methods == null)
                                return null;
 
@@ -5846,7 +5847,14 @@ namespace Mono.CSharp {
                                        continue;
 
                                if ((restrictions & Restrictions.CovariantDelegate) != 0 && !Delegate.IsTypeCovariant (ec, a.Expr.Type, pt)) {
-                                       custom_errors.NoArgumentMatch (ec, member);
+                                       if (a.IsExtensionType) {
+                                               // TODO: Should report better message type, something similar to CS1928/1929 instead of
+                                               // CS1061 but that still better than confusing CS0123
+                                               var ma = new MemberAccess (a.Expr, member.Name, loc);
+                                               ma.Error_TypeDoesNotContainDefinition (ec, a.Expr.Type, ma.Name);
+                                       } else {
+                                               custom_errors.NoArgumentMatch (ec, member);
+                                       }
                                        return false;
                                }
 
index 612baf26527a03be11e77305be488908d9b30791..017ef439f11c42f6a74ebe9dbed7935ab733b6a4 100644 (file)
@@ -9716,7 +9716,7 @@ namespace Mono.CSharp
                                        // Try to look for extension method when member lookup failed
                                        //
                                        if (MethodGroupExpr.IsExtensionMethodArgument (expr)) {
-                                               var methods = rc.LookupExtensionMethod (expr_type, Name, lookup_arity);
+                                               var methods = rc.LookupExtensionMethod (Name, lookup_arity);
                                                if (methods != null) {
                                                        var emg = new ExtensionMethodGroupExpr (methods, expr, loc);
                                                        if (HasTypeArguments) {
index 53c74714d4c4ba5dc1d47445651494e8bef27962..29d8c7981046ac6b12ab3b0587995d36b40e5404 100644 (file)
@@ -873,7 +873,7 @@ namespace Mono.CSharp {
                        base.EmitContainer ();
                }
 
-               public ExtensionMethodCandidates LookupExtensionMethod (IMemberContext invocationContext, TypeSpec extensionType, string name, int arity, int position)
+               public ExtensionMethodCandidates LookupExtensionMethod (IMemberContext invocationContext, string name, int arity, int position)
                {
                        //
                        // Here we try to resume the search for extension method at the point
@@ -1502,7 +1502,7 @@ namespace Mono.CSharp {
                                throw new NotImplementedException ();
                        }
 
-                       public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
+                       public ExtensionMethodCandidates LookupExtensionMethod (string name, int arity)
                        {
                                return null;
                        }
index 0f863a7bcf1c016f89a4588e49d6f427a5d7c676..661142822f802a9f55ed7560eb510ca5c30c1f50 100644 (file)
@@ -108,7 +108,7 @@ namespace Mono.CSharp {
                        throw new NotImplementedException ();
                }
 
-               public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
+               public ExtensionMethodCandidates LookupExtensionMethod (string name, int arity)
                {
                        throw new NotImplementedException ();
                }