[mono/mono] f33bd8ad: Adds async type inference of void return type. Fixes #15238

"Marek Safar ([email protected])" <[email protected]>
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <000001419920ba6b-8b2d8052-3b8c-4a32-b0b9-e11f7f2f8751-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/cf2ac2171b7d...f33bd8ad7fe9

   Commit: f33bd8ad7fe9470b1fae626b4e425a632a0963ca
   Author: Marek Safar <[email protected]> (marek-safar)
     Date: 2013-10-08 17:30:32 GMT
      URL: https://github.com/mono/mono/commit/f33bd8ad7fe9470b1fae626b4e425a632a0963ca

Adds async type inference of void return type. Fixes #15238

Changed paths:
  M mcs/mcs/anonymous.cs
  M mcs/mcs/generic.cs
  M mcs/mcs/statement.cs
  M mcs/tests/ver-il-net_4_5.xml
Added paths:
  A mcs/tests/test-async-52.cs

Modified: mcs/mcs/anonymous.cs
===================================================================
@@ -1535,10 +1535,14 @@ public AnonymousExpression Compatible (ResolveContext ec, AnonymousExpression ae
 
 				//
 				// If e is synchronous the inferred return type is T
-				// If e is asynchronous the inferred return type is Task<T>
+				// If e is asynchronous and the body of F is either an expression classified as nothing
+				// or a statement block where no return statements have expressions, the inferred return type is Task
+				// If e is async and has an inferred result type T, the inferred return type is Task<T>
 				//
 				if (block.IsAsync && ReturnType != null) {
-					ReturnType = ec.Module.PredefinedTypes.TaskGeneric.TypeSpec.MakeGenericType (ec, new [] { ReturnType });
+					ReturnType = ReturnType.Kind == MemberKind.Void ?
+						ec.Module.PredefinedTypes.Task.TypeSpec :
+						ec.Module.PredefinedTypes.TaskGeneric.TypeSpec.MakeGenericType (ec, new [] { ReturnType });
 				}
 			}
 

Modified: mcs/mcs/generic.cs
===================================================================
@@ -2948,15 +2948,20 @@ public TypeInferenceContext ()
 
 		public void AddCommonTypeBound (TypeSpec type)
 		{
-			AddToBounds (new BoundInfo (type, BoundKind.Lower), 0);
+			AddToBounds (new BoundInfo (type, BoundKind.Lower), 0, false);
 		}
 
-		void AddToBounds (BoundInfo bound, int index)
+		public void AddCommonTypeBoundAsync (TypeSpec type)
+		{
+			AddToBounds (new BoundInfo (type, BoundKind.Lower), 0, true);
+		}
+
+		void AddToBounds (BoundInfo bound, int index, bool voidAllowed)
 		{
 			//
 			// Some types cannot be used as type arguments
 			//
-			if (bound.Type.Kind == MemberKind.Void || bound.Type.IsPointer || bound.Type.IsSpecialRuntimeType ||
+			if ((bound.Type.Kind == MemberKind.Void && !voidAllowed) || bound.Type.IsPointer || bound.Type.IsSpecialRuntimeType ||
 				bound.Type == InternalType.MethodGroup || bound.Type == InternalType.AnonymousMethod)
 				return;
 
@@ -3030,7 +3035,7 @@ public int ExactInference (TypeSpec u, TypeSpec v)
 			if (pos == -1)
 				return 0;
 
-			AddToBounds (new BoundInfo (u, BoundKind.Exact), pos);
+			AddToBounds (new BoundInfo (u, BoundKind.Exact), pos, false);
 			return 1;
 		}
 
@@ -3361,7 +3366,7 @@ int LowerBoundInference (TypeSpec u, TypeSpec v, bool inversed)
 			// If V is one of the unfixed type arguments
 			int pos = IsUnfixed (v);
 			if (pos != -1) {
-				AddToBounds (new BoundInfo (u, inversed ? BoundKind.Upper : BoundKind.Lower), pos);
+				AddToBounds (new BoundInfo (u, inversed ? BoundKind.Upper : BoundKind.Lower), pos, false);
 				return 1;
 			}			
 

Modified: mcs/mcs/statement.cs
===================================================================
@@ -902,7 +902,7 @@ protected override bool DoResolve (BlockContext ec)
 						var async_type = storey.ReturnType;
 
 						if (async_type == null && async_block.ReturnTypeInference != null) {
-							async_block.ReturnTypeInference.AddCommonTypeBound (expr.Type);
+							async_block.ReturnTypeInference.AddCommonTypeBoundAsync (expr.Type);
 							return true;
 						}
 

Added: mcs/tests/test-async-52.cs
===================================================================
@@ -0,0 +1,23 @@
+using System;
+using System.Threading.Tasks;
+
+public delegate T ActualValueDelegate<T> ();
+
+class X
+{
+	public static void Main ()
+	{
+		Matches (async () => await Throw());
+	}
+
+	static bool Matches<T>(ActualValueDelegate<T> del) where T : Task
+	{
+		del ().Wait ();
+		return true;
+	}
+
+	static async Task Throw()
+	{
+		await Task.Delay (1);
+	}
+}
\ No newline at end of file

Modified: mcs/tests/ver-il-net_4_5.xml
===================================================================
@@ -59671,6 +59671,55 @@
       </method>
     </type>
   </test>
+  <test name="test-async-52.cs">
+    <type name="ActualValueDelegate`1[T]">
+      <method name="T Invoke()" attrs="454">
+        <size>0</size>
+      </method>
+      <method name="IAsyncResult BeginInvoke(System.AsyncCallback, System.Object)" attrs="454">
+        <size>0</size>
+      </method>
+      <method name="T EndInvoke(IAsyncResult)" attrs="454">
+        <size>0</size>
+      </method>
+      <method name="Void .ctor(Object, IntPtr)" attrs="6278">
+        <size>0</size>
+      </method>
+    </type>
+    <type name="X">
+      <method name="Void Main()" attrs="150">
+        <size>37</size>
+      </method>
+      <method name="Boolean Matches[T](ActualValueDelegate`1[T])" attrs="145">
+        <size>30</size>
+      </method>
+      <method name="System.Threading.Tasks.Task Throw()" attrs="145">
+        <size>33</size>
+      </method>
+      <method name="System.Threading.Tasks.Task &lt;Main&gt;m__0()" attrs="145">
+        <size>33</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X+&lt;Throw&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>157</size>
+      </method>
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="X+&lt;Main&gt;c__async3">
+      <method name="Void MoveNext()" attrs="486">
+        <size>160</size>
+      </method>
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+  </test>
   <test name="test-cls-00.cs">
     <type name="CLSCLass_6">
       <method name="Void add_Disposed(Delegate)" attrs="2182">



_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.