[691531] Variance conversion requires type parameters to be reference types
authorMarek Safar <marek.safar@gmail.com>
Wed, 4 May 2011 11:18:15 +0000 (12:18 +0100)
committerMarek Safar <marek.safar@gmail.com>
Wed, 4 May 2011 11:19:09 +0000 (12:19 +0100)
mcs/errors/cs0266-26.cs [new file with mode: 0644]
mcs/mcs/convert.cs
mcs/tests/gtest-variance-19.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_0.xml

diff --git a/mcs/errors/cs0266-26.cs b/mcs/errors/cs0266-26.cs
new file mode 100644 (file)
index 0000000..2c8df06
--- /dev/null
@@ -0,0 +1,14 @@
+// CS0266: Cannot implicitly convert type `System.Collections.Generic.IEnumerable<T>' to `System.Collections.Generic.IEnumerable<U>'. An explicit conversion exists (are you missing a cast?)
+// Line: 12
+
+using System;
+using System.Collections.Generic;
+
+public class Test
+{
+       static void Bla<T, U> () where T : U
+       {
+               IEnumerable<T> ita = null;
+               IEnumerable<U> itu = ita;
+       }
+}
index 3283e58b35f917c4d67ebb861ff9eb19601ecad1..020c842755bf3d1c86cf09fa865cb1e7d15db426 100644 (file)
@@ -194,6 +194,11 @@ namespace Mono.CSharp {
                // Implicit reference conversions
                //
                public static bool ImplicitReferenceConversionExists (TypeSpec expr_type, TypeSpec target_type)
+               {
+                       return ImplicitReferenceConversionExists (expr_type, target_type, true);
+               }
+
+               static bool ImplicitReferenceConversionExists (TypeSpec expr_type, TypeSpec target_type, bool refOnlyTypeParameter)
                {
                        // It's here only to speed things up
                        if (target_type.IsStruct)
@@ -201,7 +206,8 @@ namespace Mono.CSharp {
 
                        switch (expr_type.Kind) {
                        case MemberKind.TypeParameter:
-                               return ImplicitTypeParameterConversion (null, (TypeParameterSpec) expr_type, target_type) != null;
+                               return ImplicitTypeParameterConversion (null, (TypeParameterSpec) expr_type, target_type) != null &&
+                                       (!refOnlyTypeParameter || TypeSpec.IsReferenceType (expr_type));
 
                        case MemberKind.Class:
                                //
@@ -698,7 +704,7 @@ namespace Mono.CSharp {
                        if (ImplicitNumericConversion (null, expr_type, target_type) != null)
                                return true;
 
-                       if (ImplicitReferenceConversionExists (expr_type, target_type))
+                       if (ImplicitReferenceConversionExists (expr_type, target_type, false))
                                return true;
 
                        if (ImplicitBoxingConversion (null, expr_type, target_type) != null)
diff --git a/mcs/tests/gtest-variance-19.cs b/mcs/tests/gtest-variance-19.cs
new file mode 100644 (file)
index 0000000..a261ea6
--- /dev/null
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+
+public class Test
+{
+       static void Bla<T, U> () where T : class, U
+       {
+               T[] ta = new T[0];
+               IEnumerable<T> ita = ta;
+               IEnumerable<U> itu = ita;
+       }
+
+       static void Main ()
+       {
+               Bla<string, object> ();
+       }
+}
index f3165511515724cdf7d4fdc7aa73915774682f3d..8f054670757536a1e36a005541ca2a80fb8c08c2 100644 (file)
       </method>
     </type>
   </test>
+  <test name="gtest-variance-19.cs">
+    <type name="Test">
+      <method name="Void Bla[T,U]()">
+        <size>12</size>
+      </method>
+      <method name="Void Main()">
+        <size>6</size>
+      </method>
+      <method name="Void .ctor()">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-variance-2.cs">
     <type name="Foo">
       <method name="System.String Bar(System.Object)">