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;
return false;
}
- if (!CheckTypeParameterConstraints (expr.TypeParameter, seen))
+ if (!CheckTypeParameterConstraints (expr.TypeParameter, ref prevConstraint, seen))
return false;
}
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) {
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; }
}
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);
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.
///
public override string GetSignatureForError ()
{
- return TypeManager.RemoveGenericArity (gt.FullName) + "<" + args.GetSignatureForError () + ">";
+ return TypeManager.CSharpName (type);
}
protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
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;
OptAttributes.Emit ();
}
- public override bool DefineMembers ()
- {
- return true;
- }
-
public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
MemberFilter filter, object criteria)
{
} else {
params_arguments_start = arg_count;
}
+
+ Type [] ptypes = methodParameters.Types;
//
// The first inference phase
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;
}
//
// 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
// 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;
// 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)
//
// 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;