2007-08-29 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / gmcs / generic.cs
index d1644dd78a2c3fc58981659d5b3d8c645d79288d..d69a74b9e9bed74d075fa4e8da2329f81cbefefb 100644 (file)
@@ -2031,6 +2031,13 @@ namespace Mono.CSharp {
                        ec.ig.Emit(OpCodes.Initobj, type);
                        temp_storage.Emit(ec);
                }
+               
+               protected override void CloneTo (CloneContext clonectx, Expression t)
+               {
+                       DefaultValueExpression target = (DefaultValueExpression) t;
+                       
+                       target.expr = expr.Clone (clonectx);
+               }
        }
 
        public class NullableType : TypeExpr
@@ -2669,22 +2676,16 @@ namespace Mono.CSharp {
                                rtype = g_args[rtype.GenericParameterPosition];
 #endif
 
-                               if (!rtype.IsGenericParameter)
-                                       continue;
-
-                               if (tic.IsUnfixed (rtype) < 0)
-                                       continue;
-
-                               ParameterData d_parameters = TypeManager.GetParameterData (mi);
-                               bool all_params_fixed = true;
-                               foreach (Type t in d_parameters.Types) {
-                                       if (!t.IsGenericParameter)
-                                               continue;
-
-                                       if (tic.IsUnfixed (t) >= 0) {
-                                               all_params_fixed = false;
-                                               break;
-                                       }
+                               bool all_params_fixed = false;
+                               if (rtype.IsGenericParameter) {
+                                       all_params_fixed = tic.IsTypeNonDependent (mi, rtype);
+                               } else if (rtype.IsGenericType) {
+                                       all_params_fixed = true;
+                                       foreach (Type t in rtype.GetGenericArguments ())
+                                               if (!tic.IsTypeNonDependent (mi, t)) {
+                                                       all_params_fixed = false;
+                                                       break;
+                                               }
                                }
 
                                if (all_params_fixed)
@@ -2821,7 +2822,7 @@ namespace Mono.CSharp {
 
                                MethodInfo invoke = Delegate.GetInvokeMethod (t, t);
                                Type rtype = invoke.ReturnType;
-                               if (!rtype.IsGenericParameter)
+                               if (!rtype.IsGenericParameter && !rtype.IsGenericType)
                                        continue;
 
 #if MS_COMPATIBLE
@@ -2832,16 +2833,17 @@ namespace Mono.CSharp {
 
                                rtype = g_args [rtype.GenericParameterPosition];
 #endif
-                               if (rtype.IsGenericParameter)
-                                       types_to_fix [rtype.GenericParameterPosition] = null;
+                               // Remove dependent types, they cannot be fixed yet
+                               RemoveDependentTypes (types_to_fix, rtype);
                        }
 
                        foreach (Type t in types_to_fix) {
                                if (t == null)
                                        continue;
 
-                               if (!FixType (IsUnfixed (t)))
+                               if (!FixType (IsUnfixed (t))) {
                                        return false;
+                               }
                        }
 
                        fixed_any = types_to_fix.Count > 0;
@@ -2898,6 +2900,23 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               public bool IsTypeNonDependent (MethodInfo mi, Type type)
+               {
+                       if (IsUnfixed (type) < 0)
+                               return false;
+
+                       ParameterData d_parameters = TypeManager.GetParameterData (mi);
+                       foreach (Type t in d_parameters.Types) {
+                               if (!t.IsGenericParameter)
+                                       continue;
+
+                               if (IsUnfixed (t) >= 0)
+                                       return false;
+                       }
+
+                       return true;
+               }
+
                public int IsUnfixed (Type type)
                {
                        if (!type.IsGenericParameter)
@@ -2940,23 +2959,23 @@ namespace Mono.CSharp {
                                if (u_dim != 1)
                                        return;
 
-                               Type g_v = v.GetGenericTypeDefinition ();
-                               if ((g_v != TypeManager.generic_ilist_type) && (g_v != TypeManager.generic_icollection_type) &&
-                                       (g_v != TypeManager.generic_ienumerable_type))
-                                       return;
+                               if (v.IsGenericType) {
+                                       Type g_v = v.GetGenericTypeDefinition ();
+                                       if ((g_v != TypeManager.generic_ilist_type) && (g_v != TypeManager.generic_icollection_type) &&
+                                               (g_v != TypeManager.generic_ienumerable_type))
+                                               return;
 
-                               v_e = TypeManager.GetTypeArguments (v)[0];
+                                       v_e = TypeManager.GetTypeArguments (v)[0];
 
-                               if (u.IsByRef) {
-                                       LowerBoundInference (u_e, v_e);
+                                       if (u.IsByRef) {
+                                               LowerBoundInference (u_e, v_e);
+                                               return;
+                                       }
+                                       ExactInference (u_e, v_e);
                                        return;
                                }
-                               ExactInference (u_e, v_e);
-                               return;
-                       }
-
                        // If V is a constructed type C<V1..Vk>
-                       if (v.IsGenericType && !v.IsGenericTypeDefinition) {
+                       } else if (v.IsGenericType && !v.IsGenericTypeDefinition) {
                                Type[] ga_u = u.GetGenericArguments ();
                                Type[] ga_v = v.GetGenericArguments ();
                                if (ga_u.Length != ga_v.Length)
@@ -3019,6 +3038,20 @@ namespace Mono.CSharp {
                        LowerBoundInference (e.Type, t);
                }
 
+               static void RemoveDependentTypes (ArrayList types, Type returnType)
+               {
+                       if (returnType.IsGenericParameter) {
+                               types [returnType.GenericParameterPosition] = null;
+                               return;
+                       }
+
+                       if (returnType.IsGenericType) {
+                               foreach (Type t in returnType.GetGenericArguments ()) {
+                                       RemoveDependentTypes (types, t);
+                               }
+                       }
+               }
+
                public bool UnfixedVariableExists {
                        get {
                                foreach (Type ut in unfixed_types)