[mcs] More tweaks in betterness improvements. Fixes #41724
authorMarek Safar <masafa@microsoft.com>
Tue, 2 Aug 2016 18:54:03 +0000 (20:54 +0200)
committerMarek Safar <masafa@microsoft.com>
Tue, 2 Aug 2016 18:54:37 +0000 (20:54 +0200)
mcs/mcs/ecore.cs
mcs/tests/gtest-637.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml

index e0e5b6f4748d3a4f4da983f54eb16973b1859dd8..4386f93115a197fe081f0e882270c59d29b42df2 100644 (file)
@@ -4599,10 +4599,11 @@ namespace Mono.CSharp {
                                return IsBetterConversionTarget (rc, p, q);
                        }
 
+                       var p_orig = p;
                        if (p.IsNullableType) {
                                p = Nullable.NullableInfo.GetUnderlyingType (p);
                                if (!BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (p))
-                                       return 0;
+                                       return BetterTypeConversionImplicitConversion (rc, p_orig, q);
 
                                //
                                // Spec expects implicit conversion check between p and q, q and p
@@ -4615,10 +4616,11 @@ namespace Mono.CSharp {
                                        return 2;
                        }
 
+                       var q_orig = q;
                        if (q.IsNullableType) {
                                q = Nullable.NullableInfo.GetUnderlyingType (q);
                                if (!BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (q))
-                                       return 0;
+                                       return BetterTypeConversionImplicitConversion (rc, p_orig, q_orig);
 
                                if (q == p)
                                        return 1;
@@ -4699,12 +4701,17 @@ namespace Mono.CSharp {
                                break;
                        }
 
+                       return BetterTypeConversionImplicitConversion (ec, p, q);
+               }
+
+               static int BetterTypeConversionImplicitConversion (ResolveContext rc, TypeSpec p, TypeSpec q)
+               {
                        // TODO: this is expensive
                        Expression p_tmp = new EmptyExpression (p);
                        Expression q_tmp = new EmptyExpression (q);
 
-                       bool p_to_q = Convert.ImplicitConversionExists (ec, p_tmp, q);
-                       bool q_to_p = Convert.ImplicitConversionExists (ec, q_tmp, p);
+                       bool p_to_q = Convert.ImplicitConversionExists (rc, p_tmp, q);
+                       bool q_to_p = Convert.ImplicitConversionExists (rc, q_tmp, p);
 
                        if (p_to_q && !q_to_p)
                                return 1;
diff --git a/mcs/tests/gtest-637.cs b/mcs/tests/gtest-637.cs
new file mode 100644 (file)
index 0000000..f08c850
--- /dev/null
@@ -0,0 +1,26 @@
+using System;
+
+public struct nint
+{
+       public static implicit operator nint (int v)
+       {
+               return 0;
+       }
+}
+
+public class MainClass 
+{
+       static void Test (string key, int? value)
+       {
+       }
+
+       static void Test (string key, nint? value)
+       {
+               throw new ApplicationException ();
+       }
+
+       public static void Main ()
+       {
+               Test (null, int.MinValue);
+       }
+}
index 79e1b18bf10b992f0e7b5578a81fb54ac33b8a94..c705efa9a031fbfcd360998fccab5c8d635e52ed 100644 (file)
       </method>
     </type>
   </test>
+  <test name="gtest-637.cs">
+    <type name="nint">
+      <method name="nint op_Implicit(Int32)" attrs="2198">
+        <size>15</size>
+      </method>
+    </type>
+    <type name="MainClass">
+      <method name="Void Test(System.String, System.Nullable`1[System.Int32])" attrs="145">
+        <size>2</size>
+      </method>
+      <method name="Void Test(System.String, System.Nullable`1[nint])" attrs="145">
+        <size>7</size>
+      </method>
+      <method name="Void Main()" attrs="150">
+        <size>18</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-anontype-01.cs">
     <type name="Test">
       <method name="Int32 Main()" attrs="150">