Don't report ambiguous error when a user operator conflicts with build-in type user...
authorMarek Safar <marek.safar@gmail.com>
Tue, 17 Jan 2012 11:26:45 +0000 (11:26 +0000)
committerMarek Safar <marek.safar@gmail.com>
Tue, 17 Jan 2012 12:34:12 +0000 (12:34 +0000)
mcs/mcs/membercache.cs
mcs/tests/test-840.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_5.xml

index 8a92ac596e31485f65f579e3466637b59d9e8074..e59b6d31fe0e0ed5def30b4817185b3d65ed5348 100644 (file)
@@ -304,24 +304,28 @@ namespace Mono.CSharp {
                {
                        if (member.Kind == MemberKind.Operator) {
                                var dt = member.DeclaringType;
-                               switch (dt.BuiltinType) {
-                               case BuiltinTypeSpec.Type.String:
-                               case BuiltinTypeSpec.Type.Delegate:
-                               case BuiltinTypeSpec.Type.MulticastDelegate:
-                                       // Some core types have user operators but they cannot be used as normal
-                                       // user operators as they are predefined and therefore having different
-                                       // rules (e.g. binary operators) by not setting the flag we hide them for
-                                       // user conversions
-                                       // TODO: Should I do this for all core types ?
-                                       break;
-                               default:
-                                       if (name == Operator.GetMetadataName (Operator.OpType.Implicit) || name == Operator.GetMetadataName (Operator.OpType.Explicit)) {
-                                               state |= StateFlags.HasConversionOperator;
-                                       } else {
-                                               state |= StateFlags.HasUserOperator;
-                                       }
 
-                                       break;
+                               //
+                               // Some core types have user operators but they cannot be used like normal
+                               // user operators as they are predefined and therefore having different
+                               // rules (e.g. binary operators) by not setting the flag we hide them for
+                               // user conversions
+                               //
+                               if (!BuiltinTypeSpec.IsPrimitiveType (dt)) {
+                                       switch (dt.BuiltinType) {
+                                       case BuiltinTypeSpec.Type.String:
+                                       case BuiltinTypeSpec.Type.Delegate:
+                                       case BuiltinTypeSpec.Type.MulticastDelegate:
+                                               break;
+                                       default:
+                                               if (name == Operator.GetMetadataName (Operator.OpType.Implicit) || name == Operator.GetMetadataName (Operator.OpType.Explicit)) {
+                                                       state |= StateFlags.HasConversionOperator;
+                                               } else {
+                                                       state |= StateFlags.HasUserOperator;
+                                               }
+
+                                               break;
+                                       }
                                }
                        }
 
diff --git a/mcs/tests/test-840.cs b/mcs/tests/test-840.cs
new file mode 100644 (file)
index 0000000..5c4a93a
--- /dev/null
@@ -0,0 +1,37 @@
+struct R
+{
+       public static bool operator < (R left, R right)
+       {
+               return true;
+       }
+
+       public static bool operator > (R left, R right)
+       {
+               return false;
+       }
+       
+       public static implicit operator float(R r)
+       {
+               return 5;
+       }
+       
+       public static implicit operator R(float f)
+       {
+               return new R ();
+       }
+}
+
+class C
+{
+       public static int Main ()
+       {
+               var r = new R ();
+               float f = 999f;
+               
+               bool b = f < r;
+               if (!b)
+                       return 1;
+               
+               return 0;
+       }
+}
\ No newline at end of file
index 1300871eb4a494e4acfe00593b1c86f417f9a623..1d9fc6adf46d2b9b7002fcc78d8c05ec6ffc7393 100644 (file)
       </method>
     </type>
   </test>
+  <test name="test-840.cs">
+    <type name="R">
+      <method name="Boolean op_LessThan(R, R)">
+        <size>2</size>
+      </method>
+      <method name="Boolean op_GreaterThan(R, R)">
+        <size>2</size>
+      </method>
+      <method name="Single op_Implicit(R)">
+        <size>6</size>
+      </method>
+      <method name="R op_Implicit(Single)">
+        <size>10</size>
+      </method>
+    </type>
+    <type name="C">
+      <method name="Int32 Main()">
+        <size>37</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-85.cs">
     <type name="X">
       <method name="Void .ctor()">