throw new NotImplementedException ();
}
- public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext ec)
+ public override FullNamedExpression ResolveAsTypeOrNamespace (IMemberContext mc, bool allowUnboundTypeArguments)
{
throw new NotImplementedException ();
}
continue;
if (obsoleteCheck) {
- ObsoleteAttribute obsolete_attr = t.GetAttributeObsolete ();
- if (obsolete_attr != null)
- AttributeTester.Report_ObsoleteMessage (obsolete_attr, t.GetSignatureForError (), c.Location, context.Module.Compiler.Report);
+ t.CheckObsoleteness (context, c.Location);
}
ConstraintChecker.Check (context, t, c.Location);
spec.SetMetaInfo (type);
}
+ public void Define (TypeParameter tp)
+ {
+ builder = tp.builder;
+ }
+
public void EmitConstraints (GenericTypeParameterBuilder builder)
{
var attr = GenericParameterAttributes.None;
var meta_constraints = new List<MetaType> (spec.TypeArguments.Length);
foreach (var c in spec.TypeArguments) {
//
- // Inflated type parameters can collide with special constraint types, don't
+ // Inflated type parameters can collide with base type constraint, don't
// emit any such type parameter.
//
- if (c.BuiltinType == BuiltinTypeSpec.Type.Object || c.BuiltinType == BuiltinTypeSpec.Type.ValueType)
+ if (c.IsClass && spec.BaseType.BuiltinType != BuiltinTypeSpec.Type.Object)
continue;
meta_constraints.Add (c.GetMetaInfo ());
continue;
}
- types [i] = ((TypeParameterSpec)t).GetEffectiveBase ();
+ var tps = t as TypeParameterSpec;
+ types [i] = tps != null ? tps.GetEffectiveBase () : t;
}
if (HasTypeConstraint)
return effective_base = Convert.FindMostEncompassedType (types);
}
- public override string GetSignatureForDocumentation ()
+ public override string GetSignatureForDocumentation (bool explicitName)
{
+ if (explicitName)
+ return Name;
+
var prefix = IsMethodOwned ? "``" : "`";
return prefix + DeclaredPosition;
}
//
bool found;
if (!TypeSpecComparer.Override.IsEqual (BaseType, other.BaseType)) {
- if (other.targs == null)
- return false;
-
found = false;
- foreach (var otarg in other.targs) {
- if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
- found = true;
- break;
+ if (other.targs != null) {
+ foreach (var otarg in other.targs) {
+ if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
+ found = true;
+ break;
+ }
+ }
+ } else if (targs != null) {
+ foreach (var targ in targs) {
+ if (TypeSpecComparer.Override.IsEqual (targ, other.BaseType)) {
+ found = true;
+ break;
+ }
}
}
if (other.targs != null) {
foreach (var otarg in other.targs) {
- if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
+ if (TypeSpecComparer.Override.IsEqual (iface, otarg)) {
found = true;
break;
}
// Check interfaces implementation <- definition
if (other.InterfacesDefined != null) {
- if (InterfacesDefined == null)
- return false;
-
//
// Iterate over inflated interfaces
//
foreach (var oiface in other.Interfaces) {
found = false;
- foreach (var iface in Interfaces) {
- if (TypeSpecComparer.Override.IsEqual (iface, oiface)) {
- found = true;
- break;
+
+ if (InterfacesDefined != null) {
+ foreach (var iface in Interfaces) {
+ if (TypeSpecComparer.Override.IsEqual (iface, oiface)) {
+ found = true;
+ break;
+ }
+ }
+ } else if (targs != null) {
+ foreach (var targ in targs) {
+ if (TypeSpecComparer.Override.IsEqual (targ, oiface)) {
+ found = true;
+ break;
+ }
}
}
// Check type parameters implementation -> definition
if (targs != null) {
- if (other.targs == null)
- return false;
-
foreach (var targ in targs) {
found = false;
- foreach (var otarg in other.targs) {
- if (TypeSpecComparer.Override.IsEqual (targ, otarg)) {
- found = true;
- break;
+
+ if (other.targs != null) {
+ foreach (var otarg in other.targs) {
+ if (TypeSpecComparer.Override.IsEqual (targ, otarg)) {
+ found = true;
+ break;
+ }
+ }
+ }
+
+ if (other.InterfacesDefined != null && !found) {
+ foreach (var iface in other.Interfaces) {
+ if (TypeSpecComparer.Override.IsEqual (iface, targ)) {
+ found = true;
+ break;
+ }
}
}
+ if (!found)
+ found = TypeSpecComparer.Override.IsEqual (targ, other.BaseType);
+
if (!found)
return false;
}
{
cache = new MemberCache ();
+ if (targs != null) {
+ foreach (var ta in targs) {
+ var tps = ta as TypeParameterSpec;
+ var b_type = tps == null ? ta : tps.GetEffectiveBase ();
+
+ //
+ // Find the most specific type when base type was inflated from base constraints
+ //
+ if (b_type != null && !b_type.IsStructOrEnum && TypeSpec.IsBaseClass (b_type, BaseType, false))
+ BaseType = b_type;
+ }
+ }
+
//
// For a type parameter the membercache is the union of the sets of members of the types
// specified as a primary constraint or secondary constraint
//
- if (BaseType.BuiltinType != BuiltinTypeSpec.Type.Object && BaseType.BuiltinType != BuiltinTypeSpec.Type.ValueType)
+ if (BaseType.BuiltinType != BuiltinTypeSpec.Type.Object && BaseType.BuiltinType != BuiltinTypeSpec.Type.ValueType) {
cache.AddBaseType (BaseType);
+ }
if (InterfacesDefined != null) {
foreach (var iface_type in InterfacesDefined) {
}
}
+ //
+ // Import interfaces after base type to match behavior from ordinary classes
+ //
if (targs != null) {
foreach (var ta in targs) {
var tps = ta as TypeParameterSpec;
- IList<TypeSpec> ifaces;
- if (tps != null) {
- var b_type = tps.GetEffectiveBase ();
- if (b_type != null && b_type.BuiltinType != BuiltinTypeSpec.Type.Object && b_type.BuiltinType != BuiltinTypeSpec.Type.ValueType)
- cache.AddBaseType (b_type);
-
- ifaces = tps.InterfacesDefined;
- } else {
- ifaces = ta.Interfaces;
- }
+ var ifaces = tps == null ? ta.Interfaces : tps.InterfacesDefined;
if (ifaces != null) {
foreach (var iface_type in ifaces) {
if (ac != null)
return ArrayContainer.MakeType (context.Module, et, ac.Rank);
+ if (ec is PointerContainer)
+ return PointerContainer.MakeType (context.Module, et);
+
throw new NotImplementedException ();
}
return definition.GetMetaInfo ().MakeGenericType (all.ToArray ());
}
+ public override void CheckObsoleteness (IMemberContext mc, Location loc)
+ {
+ base.CheckObsoleteness (mc, loc);
+
+ foreach (var ta in TypeArguments)
+ ta.CheckObsoleteness (mc, loc);
+ }
+
public override ObsoleteAttribute GetAttributeObsolete ()
{
return open_type.GetAttributeObsolete ();
/// <summary>
/// Resolve the type arguments.
/// </summary>
- public virtual bool Resolve (IMemberContext ec)
+ public virtual bool Resolve (IMemberContext ec, bool allowUnbound)
{
if (atypes != null)
return true;
public class UnboundTypeArguments : TypeArguments
{
- public UnboundTypeArguments (int arity)
+ Location loc;
+
+ public UnboundTypeArguments (int arity, Location loc)
: base (new FullNamedExpression[arity])
{
+ this.loc = loc;
}
public override bool IsEmpty {
}
}
- public override bool Resolve (IMemberContext ec)
+ public override bool Resolve (IMemberContext mc, bool allowUnbound)
{
+ if (!allowUnbound) {
+ mc.Module.Compiler.Report.Error (7003, loc, "Unbound generic name is not valid in this context");
+ }
+
// Nothing to be resolved
return true;
}
return type.GetSignatureForError ();
}
- public override TypeSpec ResolveAsType (IMemberContext mc)
+ public override TypeSpec ResolveAsType (IMemberContext mc, bool allowUnboundTypeArguments = false)
{
if (eclass != ExprClass.Unresolved)
return type;
- if (!args.Resolve (mc))
+ if (!args.Resolve (mc, allowUnboundTypeArguments))
return null;
TypeSpec[] atypes = args.Arguments;
//
public bool CheckAll (MemberSpec context, TypeSpec[] targs, TypeParameterSpec[] tparams, Location loc)
{
+ if (targs == null)
+ return true;
+
for (int i = 0; i < tparams.Length; i++) {
var targ = targs[i];
if (!CheckConstraint (context, targ, tparams [i], loc))
//
// Tracks successful rate of type inference
//
- int score = int.MaxValue;
+ int score;
readonly Arguments arguments;
readonly int arg_count;
AnonymousMethodExpression am = a.Expr as AnonymousMethodExpression;
if (am != null) {
if (am.ExplicitTypeInference (tic, method_parameter))
- --score;
+ ++score;
continue;
}
if (a.IsByRef) {
- score -= tic.ExactInference (a.Type, method_parameter);
+ score += tic.ExactInference (a.Type, method_parameter);
continue;
}
continue;
if (TypeSpec.IsValueType (method_parameter)) {
- score -= tic.LowerBoundInference (a.Type, method_parameter);
+ score += tic.LowerBoundInference (a.Type, method_parameter);
continue;
}
//
// Otherwise an output type inference is made
//
- score -= tic.OutputTypeInference (ec, a.Expr, method_parameter);
+ score += tic.OutputTypeInference (ec, a.Expr, method_parameter);
}
//
if (arguments[i] == null)
continue;
- score -= tic.OutputTypeInference (ec, arguments[i].Expr, t_i);
+ score += tic.OutputTypeInference (ec, arguments[i].Expr, t_i);
}
}
// Some types cannot be used as type arguments
//
if ((bound.Type.Kind == MemberKind.Void && !voidAllowed) || bound.Type.IsPointer || bound.Type.IsSpecialRuntimeType ||
- bound.Type == InternalType.MethodGroup || bound.Type == InternalType.AnonymousMethod)
+ bound.Type == InternalType.MethodGroup || bound.Type == InternalType.AnonymousMethod || bound.Type == InternalType.VarOutType)
return;
var a = bounds [index];
continue;
}
- if (TypeManager.IsGenericType (t))
- return AllTypesAreFixed (TypeManager.GetTypeArguments (t));
+ if (t.IsGeneric && !AllTypesAreFixed (t.TypeArguments))
+ return false;
}
return true;
continue;
if (!applicable[cii])
- break;
+ continue;
//
// For each exact bound U of Xi all types Uj which are not identical
continue;
if (!applicable[cii])
- break;
+ continue;
//
// For each lower bound U of Xi all types Uj to which there is not an implicit conversion
continue;
if (!applicable[cii])
- break;
+ continue;
//
// For each upper bound U of Xi all types Uj from which there is not an implicit conversion