2010-06-18 Marek Safar <marek.safar@gmail.com>
authorMarek Safar <marek.safar@gmail.com>
Fri, 18 Jun 2010 14:19:12 +0000 (14:19 -0000)
committerMarek Safar <marek.safar@gmail.com>
Fri, 18 Jun 2010 14:19:12 +0000 (14:19 -0000)
* convert.cs, typespec.cs, method.cs: Fixed few more dynamic
conversion.

svn path=/trunk/mcs/; revision=159137

mcs/mcs/ChangeLog
mcs/mcs/convert.cs
mcs/mcs/method.cs
mcs/mcs/typespec.cs

index 0f9860301d65bd7501a1fab1cd08f8803b7e9dcd..1ba1a53ee99fefac6141e35ae89668c33aac4855 100644 (file)
@@ -1,3 +1,8 @@
+2010-06-18  Marek Safar  <marek.safar@gmail.com>
+
+       * convert.cs, typespec.cs, method.cs: Fixed few more dynamic
+       conversion.
+
 2010-06-18  Marek Safar  <marek.safar@gmail.com>
 
        * typemanager.cs, namespace.cs: Report more predefined types and
index ac86ece720bbbf8ae17b8d0ce1bfabef0da59dba..207fa890f8b44e326d476f06c1fc868c30cb1658 100644 (file)
@@ -113,6 +113,16 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+                       //
+                       // LAMESPEC: From T to dynamic type
+                       //
+                       if (target_type == InternalType.Dynamic) {
+                               if (expr_type.IsReferenceType)
+                                       return new ClassCast (expr, target_type);
+
+                               return new BoxedCast (expr, target_type);
+                       }
+
                        //
                        // From T to its effective base class C
                        // From T to any base class of C
index 8ba78f8e94593641239cd7b2d6423c51f10637fc..43d8f39f73fb7384c1a2cdfd5a4fa1fa8903cefc 100644 (file)
@@ -2317,57 +2317,52 @@ namespace Mono.CSharp {
                        if (TypeManager.IsNullableType (return_type))
                                return_type_unwrap = TypeManager.GetTypeArguments (return_type) [0];
 
-                       if ((return_type == InternalType.Dynamic || first_arg_type == InternalType.Dynamic) && parameters.Count == 1) {
-                               Report.Error (1964, Location,
-                                       "User-defined operator `{0}' cannot convert to or from the dynamic type",
-                                       GetSignatureForError ());
-
-                               return false;
-                       }
-
                        //
                        // Rules for conversion operators
                        //
                        if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
-                               if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type){
+                               if (first_arg_type_unwrap == return_type_unwrap && first_arg_type_unwrap == declaring_type) {
                                        Report.Error (555, Location,
                                                "User-defined operator cannot take an object of the enclosing type and convert to an object of the enclosing type");
                                        return false;
                                }
-                               
+
                                TypeSpec conv_type;
                                if (TypeManager.IsEqual (declaring_type, return_type) || declaring_type == return_type_unwrap) {
                                        conv_type = first_arg_type;
                                } else if (TypeManager.IsEqual (declaring_type, first_arg_type) || declaring_type == first_arg_type_unwrap) {
                                        conv_type = return_type;
                                } else {
-                                       Report.Error (556, Location, 
+                                       Report.Error (556, Location,
                                                "User-defined conversion must convert to or from the enclosing type");
                                        return false;
                                }
 
-                               //
-                               // Because IsInterface and IsClass are not supported
-                               //
-                               if (!TypeManager.IsGenericParameter (conv_type)) {
-                                       if (conv_type.IsInterface) {
-                                               Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
+                               if (conv_type == InternalType.Dynamic) {
+                                       Report.Error (1964, Location,
+                                               "User-defined conversion `{0}' cannot convert to or from the dynamic type",
+                                               GetSignatureForError ());
+
+                                       return false;
+                               }
+
+                               if (conv_type.IsInterface) {
+                                       Report.Error (552, Location, "User-defined conversion `{0}' cannot convert to or from an interface type",
+                                               GetSignatureForError ());
+                                       return false;
+                               }
+
+                               if (conv_type.IsClass) {
+                                       if (TypeManager.IsSubclassOf (declaring_type, conv_type)) {
+                                               Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
                                                        GetSignatureForError ());
                                                return false;
                                        }
 
-                                       if (conv_type.IsClass) {
-                                               if (TypeManager.IsSubclassOf (declaring_type, conv_type)) {
-                                                       Report.Error (553, Location, "User-defined conversion `{0}' cannot convert to or from a base class",
-                                                               GetSignatureForError ());
-                                                       return false;
-                                               }
-
-                                               if (TypeManager.IsSubclassOf (conv_type, declaring_type)) {
-                                                       Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
-                                                               GetSignatureForError ());
-                                                       return false;
-                                               }
+                                       if (TypeManager.IsSubclassOf (conv_type, declaring_type)) {
+                                               Report.Error (554, Location, "User-defined conversion `{0}' cannot convert to or from a derived class",
+                                                       GetSignatureForError ());
+                                               return false;
                                        }
                                }
                        } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
@@ -2390,15 +2385,15 @@ namespace Mono.CSharp {
                                                return false;
                                        }
                                }
-                               
-                               if (!TypeManager.IsEqual (first_arg_type_unwrap, declaring_type)){
+
+                               if (!TypeManager.IsEqual (first_arg_type_unwrap, declaring_type)) {
                                        Report.Error (562, Location,
                                                "The parameter type of a unary operator must be the containing type");
                                        return false;
                                }
-                               
+
                                if (OperatorType == OpType.True || OperatorType == OpType.False) {
-                                       if (return_type != TypeManager.bool_type){
+                                       if (return_type != TypeManager.bool_type) {
                                                Report.Error (
                                                        215, Location,
                                                        "The return type of operator True or False " +
@@ -2406,13 +2401,13 @@ namespace Mono.CSharp {
                                                return false;
                                        }
                                }
-                               
+
                        } else if (!TypeManager.IsEqual (first_arg_type_unwrap, declaring_type)) {
                                // Checks for Binary operators
 
-                               var second_arg_type = ParameterTypes [1];
+                               var second_arg_type = ParameterTypes[1];
                                if (TypeManager.IsNullableType (second_arg_type))
-                                       second_arg_type = TypeManager.GetTypeArguments (second_arg_type) [0];
+                                       second_arg_type = TypeManager.GetTypeArguments (second_arg_type)[0];
 
                                if (!TypeManager.IsEqual (second_arg_type, declaring_type)) {
                                        Report.Error (563, Location,
index d31b8b22e67a0159e344d5645bf22efc217242c2..22278a08dacd4806887da44e02ad0cfb9f93184e 100644 (file)
@@ -617,12 +617,23 @@ namespace Mono.CSharp
                                if (type1.MemberDefinition != target_type_def)
                                        return false;
 
-                               if (!type1.IsInterface && !type1.IsDelegate)
-                                       return false;
-
                                var t1_targs = type1.TypeArguments;
                                var t2_targs = type2.TypeArguments;
                                var targs_definition = target_type_def.TypeParameters;
+
+                               if (!type1.IsInterface && !type1.IsDelegate) {
+                                       //
+                                       // Internal compiler variance between G<object> and G<dynamic>
+                                       //
+                                       for (int i = 0; i < targs_definition.Length; ++i) {
+                                               if ((t1_targs[i] != TypeManager.object_type && t1_targs[i] != InternalType.Dynamic) ||
+                                                       (t2_targs[i] != TypeManager.object_type && t2_targs[i] != InternalType.Dynamic))
+                                                       return false;
+                                       }
+
+                                       return true;
+                               }
+
                                for (int i = 0; i < targs_definition.Length; ++i) {
                                        Variance v = targs_definition[i].Variance;
                                        if (v == Variance.None) {