Nothing to see here
[mono.git] / mcs / mcs / generic.cs
index 0e2bcd474f6a8e4ce6ba01c6b20bddba52ce9072..fa210289ecf3efe896b27a4421e47b52f5cfb926 100644 (file)
@@ -344,26 +344,52 @@ namespace Mono.CSharp {
                        else
                                effective_base_type = TypeManager.object_type;
 
+                       if ((attrs & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0)
+                               attrs |= GenericParameterAttributes.DefaultConstructorConstraint;
+
                        resolved = true;
                        return true;
                }
 
-               bool CheckTypeParameterConstraints (TypeParameter tparam, Hashtable seen)
+               bool CheckTypeParameterConstraints (TypeParameter tparam, ref TypeExpr prevConstraint, ArrayList seen)
                {
-                       seen.Add (tparam, true);
+                       seen.Add (tparam);
 
                        Constraints constraints = tparam.Constraints;
                        if (constraints == null)
                                return true;
 
                        if (constraints.HasValueTypeConstraint) {
-                               Report.Error (456, loc, "Type parameter `{0}' has " +
-                                             "the `struct' constraint, so it cannot " +
-                                             "be used as a constraint for `{1}'",
-                                             tparam.Name, name);
+                               Report.Error (456, loc,
+                                       "Type parameter `{0}' has the `struct' constraint, so it cannot be used as a constraint for `{1}'",
+                                       tparam.Name, name);
                                return false;
                        }
 
+                       //
+                       //  Checks whether there are no conflicts between type parameter constraints
+                       //
+                       //   class Foo<T, U>
+                       //      where T : A
+                       //      where U : A, B  // A and B are not convertible
+                       //
+                       if (constraints.HasClassConstraint) {
+                               if (prevConstraint != null) {
+                                       Type t2 = constraints.ClassConstraint;
+                                       TypeExpr e2 = constraints.class_constraint;
+
+                                       if (!Convert.ImplicitReferenceConversionExists (prevConstraint, t2) &&
+                                               !Convert.ImplicitReferenceConversionExists (e2, prevConstraint.Type)) {
+                                               Report.Error (455, loc,
+                                                       "Type parameter `{0}' inherits conflicting constraints `{1}' and `{2}'",
+                                                       name, TypeManager.CSharpName (prevConstraint.Type), TypeManager.CSharpName (t2));
+                                               return false;
+                                       }
+                               }
+
+                               prevConstraint = constraints.class_constraint;
+                       }
+
                        if (constraints.type_param_constraints == null)
                                return true;
 
@@ -375,7 +401,7 @@ namespace Mono.CSharp {
                                        return false;
                                }
 
-                               if (!CheckTypeParameterConstraints (expr.TypeParameter, seen))
+                               if (!CheckTypeParameterConstraints (expr.TypeParameter, ref prevConstraint, seen))
                                        return false;
                        }
 
@@ -401,10 +427,14 @@ namespace Mono.CSharp {
                                        return false;
                        }
 
-                       foreach (TypeParameterExpr expr in type_param_constraints) {
-                               Hashtable seen = new Hashtable ();
-                               if (!CheckTypeParameterConstraints (expr.TypeParameter, seen))
-                                       return false;
+                       if (type_param_constraints.Count != 0) {
+                               ArrayList seen = new ArrayList ();
+                               TypeExpr prev_constraint = class_constraint;
+                               foreach (TypeParameterExpr expr in type_param_constraints) {
+                                       if (!CheckTypeParameterConstraints (expr.TypeParameter, ref prev_constraint, seen))
+                                               return false;
+                                       seen.Clear ();
+                               }
                        }
 
                        for (int i = 0; i < iface_constraints.Count; ++i) {
@@ -424,66 +454,6 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               /// <summary>
-               ///   Check whether there are no conflicts in our type parameter constraints.
-               ///
-               ///   This is an example:
-               ///
-               ///   class Foo<T,U>
-               ///      where T : class
-               ///      where U : T, struct
-               /// </summary>
-               public bool CheckDependencies ()
-               {
-                       foreach (TypeParameterExpr expr in type_param_constraints) {
-                               if (!CheckDependencies (expr.TypeParameter))
-                                       return false;
-                       }
-
-                       return true;
-               }
-
-               bool CheckDependencies (TypeParameter tparam)
-               {
-                       Constraints constraints = tparam.Constraints;
-                       if (constraints == null)
-                               return true;
-
-                       if (HasValueTypeConstraint && constraints.HasClassConstraint) {
-                               Report.Error (455, loc, "Type parameter `{0}' inherits " +
-                                             "conflicting constraints `{1}' and `{2}'",
-                                             name, TypeManager.CSharpName (constraints.ClassConstraint),
-                                             "System.ValueType");
-                               return false;
-                       }
-
-                       if (HasClassConstraint && constraints.HasClassConstraint) {
-                               Type t1 = ClassConstraint;
-                               TypeExpr e1 = class_constraint;
-                               Type t2 = constraints.ClassConstraint;
-                               TypeExpr e2 = constraints.class_constraint;
-
-                               if (!Convert.ImplicitReferenceConversionExists (e1, t2) &&
-                                   !Convert.ImplicitReferenceConversionExists (e2, t1)) {
-                                       Report.Error (455, loc,
-                                                     "Type parameter `{0}' inherits " +
-                                                     "conflicting constraints `{1}' and `{2}'",
-                                                     name, TypeManager.CSharpName (t1), TypeManager.CSharpName (t2));
-                                       return false;
-                               }
-                       }
-
-                       if (constraints.type_param_constraints == null)
-                               return true;
-
-                       foreach (TypeParameterExpr expr in constraints.type_param_constraints) {
-                               if (!CheckDependencies (expr.TypeParameter))
-                                       return false;
-                       }
-
-                       return true;
-               }
-
                public override GenericParameterAttributes Attributes {
                        get { return attrs; }
                }
@@ -784,8 +754,8 @@ namespace Mono.CSharp {
                        if (gc == null)
                                return true;
 
-                       if (gc.HasClassConstraint)
-                               type.SetBaseTypeConstraint (gc.ClassConstraint);
+                       if (gc.HasClassConstraint || gc.HasValueTypeConstraint)
+                               type.SetBaseTypeConstraint (gc.EffectiveBaseClass);
 
                        type.SetInterfaceConstraints (gc.InterfaceConstraints);
                        type.SetGenericParameterAttributes (gc.Attributes);
@@ -794,23 +764,6 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               /// <summary>
-               ///   Check whether there are no conflicts in our type parameter constraints.
-               ///
-               ///   This is an example:
-               ///
-               ///   class Foo<T,U>
-               ///      where T : class
-               ///      where U : T, struct
-               /// </summary>
-               public bool CheckDependencies ()
-               {
-                       if (constraints != null)
-                               return constraints.CheckDependencies ();
-
-                       return true;
-               }
-
                /// <summary>
                ///   This is called for each part of a partial generic type definition.
                ///
@@ -1044,7 +997,7 @@ namespace Mono.CSharp {
                                if (t == null)
                                        return null;
                                if (t.IsGenericParameter)
-                                       return dargs [t.GenericParameterPosition];
+                                       return t.GenericParameterPosition < dargs.Length ? dargs [t.GenericParameterPosition] : t;
                                if (t.IsGenericType) {
                                        Type[] args = t.GetGenericArguments ();
                                        Type[] inflated = new Type [args.Length];
@@ -1377,7 +1330,7 @@ namespace Mono.CSharp {
 
                public override string GetSignatureForError ()
                {
-                       return TypeManager.RemoveGenericArity (gt.FullName) + "<" + args.GetSignatureForError () + ">";
+                       return TypeManager.CSharpName (type);
                }
 
                protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
@@ -1886,11 +1839,8 @@ namespace Mono.CSharp {
                                            ec, mb, implementing, is_override))
                                        return false;
 
-                       bool ok = true;
-                       foreach (Parameter p in parameters.FixedParameters){
-                               if (p.Resolve (ec) == null)
-                                       ok = false;
-                       }
+                       bool ok = parameters.Resolve (ec);
+
                        if ((return_type != null) && (return_type.ResolveAsTypeTerminal (ec, false) == null))
                                ok = false;
 
@@ -1906,11 +1856,6 @@ namespace Mono.CSharp {
                                OptAttributes.Emit ();
                }
 
-               public override bool DefineMembers ()
-               {
-                       return true;
-               }
-
                public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
                                                        MemberFilter filter, object criteria)
                {
@@ -2394,6 +2339,8 @@ namespace Mono.CSharp {
                        } else {
                                params_arguments_start = arg_count;
                        }
+
+                       Type [] ptypes = methodParameters.Types;
                        
                        //
                        // The first inference phase
@@ -2409,6 +2356,9 @@ namespace Mono.CSharp {
                                                method_parameter = methodParameters.Types [params_arguments_start];
                                        else
                                                method_parameter = TypeManager.GetElementType (methodParameters.Types [params_arguments_start]);
+
+                                       ptypes = (Type[]) ptypes.Clone ();
+                                       ptypes [i] = method_parameter;
                                }
 
                                //
@@ -2436,16 +2386,16 @@ namespace Mono.CSharp {
                        // we don't need to call it in cycle
                        //
                        bool fixed_any = false;
-                       if (!tic.FixIndependentTypeArguments (methodParameters, ref fixed_any))
+                       if (!tic.FixIndependentTypeArguments (ptypes, ref fixed_any))
                                return false;
 
-                       return DoSecondPhase (ec, tic, methodParameters, !fixed_any);
+                       return DoSecondPhase (ec, tic, ptypes, !fixed_any);
                }
 
-               bool DoSecondPhase (EmitContext ec, TypeInferenceContext tic, AParametersCollection methodParameters, bool fixDependent)
+               bool DoSecondPhase (EmitContext ec, TypeInferenceContext tic, Type[] methodParameters, bool fixDependent)
                {
                        bool fixed_any = false;
-                       if (fixDependent && !tic.FixDependentTypes (methodParameters, ref fixed_any))
+                       if (fixDependent && !tic.FixDependentTypes (ref fixed_any))
                                return false;
 
                        // If no further unfixed type variables exist, type inference succeeds
@@ -2459,7 +2409,10 @@ namespace Mono.CSharp {
                        // contain unfixed type variables but the input types do not,
                        // an output type inference is made
                        for (int i = 0; i < arg_count; i++) {
-                               Type t_i = methodParameters.Types [i];
+                               
+                               // Align params arguments
+                               Type t_i = methodParameters [i >= methodParameters.Length ? methodParameters.Length - 1: i];
+                               
                                if (!TypeManager.IsDelegateType (t_i)) {
                                        if (TypeManager.DropGenericTypeArguments (t_i) != TypeManager.expression_type)
                                                continue;
@@ -2619,7 +2572,7 @@ namespace Mono.CSharp {
                // a, There is at least one type variable Xj that depends on Xi
                // b, Xi has a non-empty set of bounds
                // 
-               public bool FixDependentTypes (AParametersCollection methodParameters, ref bool fixed_any)
+               public bool FixDependentTypes (ref bool fixed_any)
                {
                        for (int i = 0; i < unfixed_types.Length; ++i) {
                                if (unfixed_types[i] == null)
@@ -2640,11 +2593,11 @@ namespace Mono.CSharp {
                //
                // All unfixed type variables Xi which depend on no Xj are fixed
                //
-               public bool FixIndependentTypeArguments (AParametersCollection methodParameters, ref bool fixed_any)
+               public bool FixIndependentTypeArguments (Type[] methodParameters, ref bool fixed_any)
                {
                        ArrayList types_to_fix = new ArrayList (unfixed_types);
-                       for (int i = 0; i < methodParameters.Types.Length; ++i) {
-                               Type t = methodParameters.Types [i];
+                       for (int i = 0; i < methodParameters.Length; ++i) {
+                               Type t = methodParameters[i];
                                if (t.IsGenericParameter)
                                        continue;