Better error reporting for async delegates
authorMarek Safar <marek.safar@gmail.com>
Fri, 16 Sep 2011 08:44:28 +0000 (09:44 +0100)
committerMarek Safar <marek.safar@gmail.com>
Mon, 19 Sep 2011 10:56:40 +0000 (11:56 +0100)
18 files changed:
mcs/errors/cs1983-2.cs [deleted file]
mcs/errors/cs1983-3.cs [deleted file]
mcs/errors/cs1991.cs [deleted file]
mcs/errors/cs1999-2.cs [deleted file]
mcs/errors/cs1999-3.cs [deleted file]
mcs/errors/cs1999-4.cs [deleted file]
mcs/errors/cs1999.cs [deleted file]
mcs/errors/cs4001.cs [new file with mode: 0644]
mcs/errors/cs4010-2.cs [new file with mode: 0644]
mcs/errors/cs4010.cs [new file with mode: 0644]
mcs/errors/cs4011-2.cs [new file with mode: 0644]
mcs/errors/cs4011-3.cs [new file with mode: 0644]
mcs/errors/cs4011-4.cs [new file with mode: 0644]
mcs/errors/cs4011.cs [new file with mode: 0644]
mcs/mcs/anonymous.cs
mcs/mcs/async.cs
mcs/mcs/cs-parser.jay
mcs/mcs/method.cs

diff --git a/mcs/errors/cs1983-2.cs b/mcs/errors/cs1983-2.cs
deleted file mode 100644 (file)
index bc9aa47..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// CS1983: The return type of an async method must be void, Task, or Task<T>
-// Line: 16
-// Compiler options: -langversion:future
-
-using System;
-using System.Threading.Tasks;
-
-class C
-{
-       static Task<int> GetInt ()
-       {
-               return null;
-       }
-       
-       public static void Main ()
-       {
-               Func<bool> a = async () => { await GetInt (); };
-       }
-}
diff --git a/mcs/errors/cs1983-3.cs b/mcs/errors/cs1983-3.cs
deleted file mode 100644 (file)
index 7ac3080..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// CS1983: The return type of an async method must be void, Task, or Task<T>
-// Line: 10
-// Compiler options: -langversion:future
-
-using System;
-
-class C
-{
-       public static void Main ()
-       {
-               Func<string> a = async delegate { };
-       }
-}
diff --git a/mcs/errors/cs1991.cs b/mcs/errors/cs1991.cs
deleted file mode 100644 (file)
index e493b0c..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// CS1991: Cannot await `void' expression
-// Line: 10
-// Compiler options: -langversion:future
-
-using System;
-
-class A
-{
-       static async void Test ()
-       {
-               await Console.WriteLine ("await");
-       }
-}
diff --git a/mcs/errors/cs1999-2.cs b/mcs/errors/cs1999-2.cs
deleted file mode 100644 (file)
index e84d5bd..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// CS1999: The awaiter type `int' must have suitable IsCompleted, OnCompleted, and GetResult members
-// Line: 16
-// Compiler options: -langversion:future
-
-static class S
-{
-       public static int GetAwaiter (this int i)
-       {
-               return 1;
-       }
-}
-
-class A
-{
-       static async void Test ()
-       {
-               await 9;
-       }
-}
\ No newline at end of file
diff --git a/mcs/errors/cs1999-3.cs b/mcs/errors/cs1999-3.cs
deleted file mode 100644 (file)
index 56c0971..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// CS1999: The awaiter type `A' must have suitable IsCompleted, OnCompleted, and GetResult members
-// Line: 16
-// Compiler options: -langversion:future
-
-static class S
-{
-       public static A GetAwaiter (this int i)
-       {
-               return new A ();
-       }
-}
-
-class A
-{
-       int IsCompleted {
-               get {
-                       return 1;
-               }
-       }
-       
-       static async void Test ()
-       {
-               await 9;
-       }
-}
diff --git a/mcs/errors/cs1999-4.cs b/mcs/errors/cs1999-4.cs
deleted file mode 100644 (file)
index 968456b..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// CS1999: The awaiter type `A' must have suitable IsCompleted, OnCompleted, and GetResult members
-// Line: 16
-// Compiler options: -langversion:future
-
-static class S
-{
-       public static A GetAwaiter (this int i)
-       {
-               return new A ();
-       }
-}
-
-class A
-{
-       bool IsCompleted {
-               get {
-                       return true;
-               }
-       }
-       
-       void OnCompleted (System.Action a)
-       {
-       }
-       
-       static async void Test ()
-       {
-               await 9;
-       }
-}
diff --git a/mcs/errors/cs1999.cs b/mcs/errors/cs1999.cs
deleted file mode 100644 (file)
index e84d5bd..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// CS1999: The awaiter type `int' must have suitable IsCompleted, OnCompleted, and GetResult members
-// Line: 16
-// Compiler options: -langversion:future
-
-static class S
-{
-       public static int GetAwaiter (this int i)
-       {
-               return 1;
-       }
-}
-
-class A
-{
-       static async void Test ()
-       {
-               await 9;
-       }
-}
\ No newline at end of file
diff --git a/mcs/errors/cs4001.cs b/mcs/errors/cs4001.cs
new file mode 100644 (file)
index 0000000..3438d07
--- /dev/null
@@ -0,0 +1,13 @@
+// CS4001: Cannot await `void' expression
+// Line: 10
+// Compiler options: -langversion:future
+
+using System;
+
+class A
+{
+       static async void Test ()
+       {
+               await Console.WriteLine ("await");
+       }
+}
diff --git a/mcs/errors/cs4010-2.cs b/mcs/errors/cs4010-2.cs
new file mode 100644 (file)
index 0000000..05dbccb
--- /dev/null
@@ -0,0 +1,13 @@
+// CS4010: Cannot convert async anonymous method to delegate type `System.Func<string>'
+// Line: 10
+// Compiler options: -langversion:future
+
+using System;
+
+class C
+{
+       public static void Main ()
+       {
+               Func<string> a = async delegate { };
+       }
+}
diff --git a/mcs/errors/cs4010.cs b/mcs/errors/cs4010.cs
new file mode 100644 (file)
index 0000000..858a9b9
--- /dev/null
@@ -0,0 +1,19 @@
+// CS4010: Cannot convert async lambda expression to delegate type `System.Func<bool>'
+// Line: 16
+// Compiler options: -langversion:future
+
+using System;
+using System.Threading.Tasks;
+
+class C
+{
+       static Task<int> GetInt ()
+       {
+               return null;
+       }
+       
+       public static void Main ()
+       {
+               Func<bool> a = async () => { await GetInt (); };
+       }
+}
diff --git a/mcs/errors/cs4011-2.cs b/mcs/errors/cs4011-2.cs
new file mode 100644 (file)
index 0000000..86176fa
--- /dev/null
@@ -0,0 +1,19 @@
+// CS4011: The awaiter type `int' must have suitable IsCompleted, OnCompleted, and GetResult members
+// Line: 16
+// Compiler options: -langversion:future
+
+static class S
+{
+       public static int GetAwaiter (this int i)
+       {
+               return 1;
+       }
+}
+
+class A
+{
+       static async void Test ()
+       {
+               await 9;
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs4011-3.cs b/mcs/errors/cs4011-3.cs
new file mode 100644 (file)
index 0000000..69e9cfb
--- /dev/null
@@ -0,0 +1,25 @@
+// CS4011: The awaiter type `A' must have suitable IsCompleted, OnCompleted, and GetResult members
+// Line: 16
+// Compiler options: -langversion:future
+
+static class S
+{
+       public static A GetAwaiter (this int i)
+       {
+               return new A ();
+       }
+}
+
+class A
+{
+       int IsCompleted {
+               get {
+                       return 1;
+               }
+       }
+       
+       static async void Test ()
+       {
+               await 9;
+       }
+}
diff --git a/mcs/errors/cs4011-4.cs b/mcs/errors/cs4011-4.cs
new file mode 100644 (file)
index 0000000..e3a4a89
--- /dev/null
@@ -0,0 +1,29 @@
+// CS4011: The awaiter type `A' must have suitable IsCompleted, OnCompleted, and GetResult members
+// Line: 16
+// Compiler options: -langversion:future
+
+static class S
+{
+       public static A GetAwaiter (this int i)
+       {
+               return new A ();
+       }
+}
+
+class A
+{
+       bool IsCompleted {
+               get {
+                       return true;
+               }
+       }
+       
+       void OnCompleted (System.Action a)
+       {
+       }
+       
+       static async void Test ()
+       {
+               await 9;
+       }
+}
diff --git a/mcs/errors/cs4011.cs b/mcs/errors/cs4011.cs
new file mode 100644 (file)
index 0000000..e84d5bd
--- /dev/null
@@ -0,0 +1,19 @@
+// CS1999: The awaiter type `int' must have suitable IsCompleted, OnCompleted, and GetResult members
+// Line: 16
+// Compiler options: -langversion:future
+
+static class S
+{
+       public static int GetAwaiter (this int i)
+       {
+               return 1;
+       }
+}
+
+class A
+{
+       static async void Test ()
+       {
+               await 9;
+       }
+}
\ No newline at end of file
index 11169c25aa854424e19ffdd2dcdcbec4b0b8f91a..aadb7a67f9a70bf716e84d4e1498fdace40aabf6 100644 (file)
@@ -1157,7 +1157,15 @@ namespace Mono.CSharp {
                                        }
                                } else {
                                        if (is_async) {
-                                               AsyncInitializer.Create (ec, body.Block, body.Parameters, ec.CurrentMemberDefinition.Parent, body.ReturnType, loc);
+                                               var rt = body.ReturnType;
+                                               if (rt.Kind != MemberKind.Void &&
+                                                       rt != ec.Module.PredefinedTypes.Task.TypeSpec &&
+                                                       !rt.IsGenericTask) {
+                                                       ec.Report.Error (4010, loc, "Cannot convert async {0} to delegate type `{1}'",
+                                                               GetSignatureForError (), type.GetSignatureForError ());
+                                               }
+
+                                               AsyncInitializer.Create (ec, body.Block, body.Parameters, ec.CurrentMemberDefinition.Parent, rt, loc);
                                        }
 
                                        am = body.Compatible (ec);
index cc458659ceb51e5567d989b60224d323d3aada25..a6aecc75c1b4baa8fd9d86edb77f835244d354c2 100644 (file)
@@ -120,12 +120,12 @@ namespace Mono.CSharp
 
                        protected override void Error_TypeDoesNotContainDefinition (ResolveContext rc, TypeSpec type, string name)
                        {
-                               Error_WrongGetAwaiter (rc, loc, type);
+                               Error_OperatorCannotBeApplied (rc, type);
                        }
 
                        protected override void Error_OperatorCannotBeApplied (ResolveContext rc, TypeSpec type)
                        {
-                               rc.Report.Error (1991, loc, "Cannot await `{0}' expression", type.GetSignatureForError ());
+                               rc.Report.Error (4001, loc, "Cannot await `{0}' expression", type.GetSignatureForError ());
                        }
                }
 
@@ -287,16 +287,9 @@ namespace Mono.CSharp
                        }
                }
 
-               static void Error_WrongGetAwaiter (ResolveContext rc, Location loc, TypeSpec type)
-               {
-                       rc.Report.Error (1986, loc,
-                               "The `await' operand type `{0}' must have suitable GetAwaiter method",
-                               type.GetSignatureForError ());
-               }
-
                void Error_WrongAwaiterPattern (ResolveContext rc, TypeSpec awaiter)
                {
-                       rc.Report.Error (1999, loc, "The awaiter type `{0}' must have suitable IsCompleted, OnCompleted, and GetResult members",
+                       rc.Report.Error (4011, loc, "The awaiter type `{0}' must have suitable IsCompleted, OnCompleted, and GetResult members",
                                awaiter.GetSignatureForError ());
                }
 
@@ -334,7 +327,10 @@ namespace Mono.CSharp
                        bc.Report.SetPrinter (old);
 
                        if (errors_printer.ErrorsCount > 0 || !MemberAccess.IsValidDotExpression (ama.Type)) {
-                               Error_WrongGetAwaiter (bc, expr.Location, expr.Type);
+                               bc.Report.Error (1986, expr.Location,
+                                       "The `await' operand type `{0}' must have suitable GetAwaiter method",
+                                       expr.Type.GetSignatureForError ());
+
                                return false;
                        }
 
@@ -427,12 +423,6 @@ namespace Mono.CSharp
 
                public static void Create (IMemberContext context, ParametersBlock block, ParametersCompiled parameters, TypeContainer host, TypeSpec returnType, Location loc)
                {
-                       if (returnType != null && returnType.Kind != MemberKind.Void &&
-                               returnType != host.Module.PredefinedTypes.Task.TypeSpec &&
-                               !returnType.IsGenericTask) {
-                               host.Compiler.Report.Error (1983, loc, "The return type of an async method must be void, Task, or Task<T>");
-                       }
-
                        for (int i = 0; i < parameters.Count; i++) {
                                Parameter p = parameters[i];
                                Parameter.Modifier mod = p.ModFlags;
index 732c4838feaf87a08879b1ad51add26eceec9836..6000a67390e13d4118d3db0b327f41bd463d0071 100644 (file)
@@ -6707,6 +6707,8 @@ static string GetTokenName (int token)
                return "add";
        case Token.ASYNC:
                return "async";
+       case Token.AWAIT:
+               return "await";         
        case Token.BASE:
                return "base";
        case Token.BREAK:
index a0c9edf8f590a09d296d25e7860cb8371a5750fb..ee4072c2def2b3bce6da8bd84ccd89a0f048d7b7 100644 (file)
@@ -1182,6 +1182,12 @@ namespace Mono.CSharp {
                                }
 
                                if ((ModFlags & Modifiers.ASYNC) != 0) {
+                                       if (ReturnType.Kind != MemberKind.Void &&
+                                               ReturnType != Module.PredefinedTypes.Task.TypeSpec &&
+                                               !ReturnType.IsGenericTask) {
+                                               Report.Error (1983, Location, "The return type of an async method must be void, Task, or Task<T>");
+                                       }
+
                                        AsyncInitializer.Create (this, block, parameters, Parent.PartialContainer, ReturnType, Location);
                                }
                        }