Implement type inference of dynamic arguments used as unknown types
authorMarek Safar <marek.safar@gmail.com>
Wed, 27 Oct 2010 15:59:12 +0000 (16:59 +0100)
committerMarek Safar <marek.safar@gmail.com>
Thu, 28 Oct 2010 12:44:31 +0000 (13:44 +0100)
mcs/mcs/generic.cs
mcs/tests/dtest-010.cs
mcs/tests/ver-il-dmcs.xml

index dfc01322f1322cf7bca9076ce983bd2754477ab0..d59cfcdccc0d74ee52e3a743b7fed5b03196d873 100644 (file)
@@ -2909,6 +2909,13 @@ namespace Mono.CSharp {
                                        if (open_v == t.MemberDefinition)
                                                u_candidates.Add (t);
 
+                                       //
+                                       // Using this trick for dynamic type inference, the spec says the type arguments are "unknown" but
+                                       // that would complicate the process a lot, instead I treat them as dynamic
+                                       //
+                                       if (t == InternalType.Dynamic)
+                                               u_candidates.Add (t);
+
                                        if (t.Interfaces != null) {
                                                foreach (var iface in t.Interfaces) {
                                                        if (open_v == iface.MemberDefinition)
@@ -2939,7 +2946,21 @@ namespace Mono.CSharp {
                                                return 1;
                                        }
 
-                                       unique_candidate_targs = TypeManager.GetTypeArguments (u_candidate);
+                                       //
+                                       // A candidate is dynamic type expression, to simplify things use dynamic
+                                       // for all type parameter of this type. For methods like this one
+                                       // 
+                                       // void M<T, U> (IList<T>, IList<U[]>)
+                                       //
+                                       // dynamic becomes both T and U when the arguments are of dynamic type
+                                       //
+                                       if (u_candidate == InternalType.Dynamic) {
+                                               unique_candidate_targs = new TypeSpec[ga_v.Length];
+                                               for (int i = 0; i < unique_candidate_targs.Length; ++i)
+                                                       unique_candidate_targs[i] = u_candidate;
+                                       } else {
+                                               unique_candidate_targs = TypeManager.GetTypeArguments (u_candidate);
+                                       }
                                }
 
                                if (unique_candidate_targs != null) {
index c9ca78901126ac48ad352fe4e136c649d1db68bd..e38e82d9e480329c43ccaf8a34beedb7dfdbbfb3 100644 (file)
@@ -21,9 +21,8 @@ class C
                if (A.Test<dynamic> (d, o).TestCall () != 1)
                        return 1;
 
-               // FIXME: Very tricky, I not sure what to do for now
-               //if (A.Test (d, o).TestCall () != 1)
-               //      return 1;
+               if (A.Test (d, o).TestCall () != 1)
+                       return 2;
 
                return 0;
        }
index b80ab8b66f2af86f2971707e6e9e0c88d1ef7c31..50e4e918129047c7f532409e00f761b3f468e265 100644 (file)
         <size>2</size>
       </method>
       <method name="Int32 Main()">
-        <size>388</size>
+        <size>743</size>
       </method>
       <method name="Void .ctor()">
         <size>7</size>
       </method>
     </type>
   </test>
+  <test name="dtest-043.cs">
+    <type name="A">
+      <method name="Int32 Main()">
+        <size>276</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="dtest-044.cs">
+    <type name="C">
+      <method name="Int32 Test[T,U](T, IComparable`1)">
+        <size>2</size>
+      </method>
+      <method name="Int32 Test_2[T](IList`1, T)">
+        <size>2</size>
+      </method>
+      <method name="Int32 Main()">
+        <size>845</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="dtest-cls-01.cs">
     <type name="A">
       <method name="Void Main()">
       </method>
     </type>
   </test>
+  <test name="gtest-541.cs">
+    <type name="Foo">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Top`1[S]">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Top`1+Base`1[S,T]">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Top`1+Base`1+Derived`1[S,T,U]">
+      <method name="Void Test()">
+        <size>1</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Test">
+      <method name="Int32 Main()">
+        <size>14</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-542.cs">
+    <type name="A`1[T]">
+      <method name="T getT()">
+        <size>0</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="A`1+B[T]">
+      <method name="A`1+B[T] getT()">
+        <size>2</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="C">
+      <method name="Int32 Main()">
+        <size>22</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-543.cs">
+    <type name="Blah`1[T]">
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Blah`1+WrapperWrapper`1[T,N]">
+      <method name="Blah`1+WrapperWrapper`1[T,N] NewWrapperWrapper(Wrapper`1[N])">
+        <size>7</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>12</size>
+      </method>
+      <method name="Void .ctor(Wrapper`1)">
+        <size>14</size>
+      </method>
+    </type>
+    <type name="Wrapper`1[U]">
+      <method name="Void .ctor(U)">
+        <size>7</size>
+      </method>
+      <method name="Void .cctor()">
+        <size>20</size>
+      </method>
+    </type>
+    <type name="C">
+      <method name="Int32 Main()">
+        <size>26</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-anon-1.cs">
     <type name="X">
       <method name="Void .ctor()">
       </method>
     </type>
   </test>
-  <test name="test-792.cs">
-    <type name="Program">
-      <method name="Void Test()">
-        <size>24</size>
-      </method>
-      <method name="Void Main()">
-        <size>1</size>
-      </method>
-      <method name="Void .ctor()">
-        <size>7</size>
-      </method>
-    </type>
-  </test>
   <test name="test-793.cs">
     <type name="MonoPointerBugTest.Program">
       <method name="Int32 Main()">
       </method>
     </type>
   </test>
+  <test name="test-anon-26.cs">
+    <type name="TestGotoLabels.GotoLabelsTest">
+      <method name="Int32 Main()">
+        <size>36</size>
+      </method>
+      <method name="Void TestMethod2(TestGotoLabels.GotoLabelsTest+MyDelegate)">
+        <size>7</size>
+      </method>
+      <method name="Void &lt;Main&gt;m__0()">
+        <size>6</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="TestGotoLabels.GotoLabelsTest+MyDelegate">
+      <method name="Void Invoke()">
+        <size>0</size>
+      </method>
+      <method name="IAsyncResult BeginInvoke(System.AsyncCallback, System.Object)">
+        <size>0</size>
+      </method>
+      <method name="Void EndInvoke(IAsyncResult)">
+        <size>0</size>
+      </method>
+      <method name="Void .ctor(Object, IntPtr)">
+        <size>0</size>
+      </method>
+    </type>
+  </test>
   <test name="test-anon-27.cs">
     <type name="X">
       <method name="Void .ctor()">