[324961] Move type constraints checks into emit where it can be safely done (fixes...
authorMarek Safar <marek.safar@gmail.com>
Thu, 7 Apr 2011 11:05:48 +0000 (12:05 +0100)
committerMarek Safar <marek.safar@gmail.com>
Thu, 7 Apr 2011 11:07:00 +0000 (12:07 +0100)
24 files changed:
mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/DynamicContext.cs
mcs/class/Microsoft.CSharp/Microsoft.CSharp.RuntimeBinder/RuntimeBinderContext.cs
mcs/errors/cs0310-6.cs [new file with mode: 0644]
mcs/errors/cs0315-4.cs [new file with mode: 0644]
mcs/errors/cs0452-5.cs [new file with mode: 0644]
mcs/errors/cs0452-6.cs [new file with mode: 0644]
mcs/errors/cs0452-7.cs [new file with mode: 0644]
mcs/errors/cs0452-8.cs [new file with mode: 0644]
mcs/errors/cs0453-6.cs [new file with mode: 0644]
mcs/errors/cs0453-7.cs [new file with mode: 0644]
mcs/errors/cs0619-56.cs [new file with mode: 0644]
mcs/mcs/class.cs
mcs/mcs/context.cs
mcs/mcs/cs-parser.jay
mcs/mcs/decl.cs
mcs/mcs/delegate.cs
mcs/mcs/ecore.cs
mcs/mcs/field.cs
mcs/mcs/generic.cs
mcs/mcs/method.cs
mcs/mcs/namespace.cs
mcs/mcs/parameter.cs
mcs/mcs/property.cs
mcs/mcs/roottypes.cs

index 38f4077ed459f177f020a561f1268d602b2d9af6..a71f11455a23bcbb0bf6ba471057dbe07adaf562 100644 (file)
@@ -94,6 +94,7 @@ namespace Microsoft.CSharp.RuntimeBinder
                                // TODO: Remove this code and rely on GetAssemblyDefinition only
                                //
                                var module = new Compiler.ModuleContainer (cc);
+                               module.HasTypesFullyDefined = true;
                                var temp = new Compiler.AssemblyDefinitionDynamic (module, "dynamic");
                                module.SetDeclaringAssembly (temp);
 
index 64430ebd9c1faeedcfdcd320b0940e0b0e1a66ee..2f6503575d7888f2d3efc4c9f477e58e25a9d88a 100644 (file)
@@ -80,12 +80,6 @@ namespace Microsoft.CSharp.RuntimeBinder
                        }
                }
 
-               public bool HasUnresolvedConstraints {
-                       get {
-                               return false;
-                       }
-               }
-
                public bool IsObsolete {
                        get {
                                // Always true to ignore obsolete attribute checks
diff --git a/mcs/errors/cs0310-6.cs b/mcs/errors/cs0310-6.cs
new file mode 100644 (file)
index 0000000..86694cf
--- /dev/null
@@ -0,0 +1,21 @@
+// CS0310: The type `Class1' must have a public parameterless constructor in order to use it as parameter `T' in the generic type or method `Class3<T>'
+// Line: 18
+
+public class Class1
+{
+       public Class1 (int i) { }
+}
+
+public class Class2<T>
+{
+}
+
+public class Class3<T> where T : new ()
+{
+}
+
+
+class A : Class2<Class3<Class1>>
+{
+}
+
diff --git a/mcs/errors/cs0315-4.cs b/mcs/errors/cs0315-4.cs
new file mode 100644 (file)
index 0000000..e79d625
--- /dev/null
@@ -0,0 +1,9 @@
+// CS0315: The type `short' cannot be used as type parameter `T' in the generic type or method `A<T>'. There is no boxing conversion from `short' to `A<short>.N1<short>'
+// Line: 4
+
+public class A<T> where T : A<short>.N1<T>
+{
+    public class N1<U>
+    {
+    }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0452-5.cs b/mcs/errors/cs0452-5.cs
new file mode 100644 (file)
index 0000000..19b3a09
--- /dev/null
@@ -0,0 +1,14 @@
+// CS0452: The type `int' must be a reference type in order to use it as type parameter `T' in the generic type or method `C<T>'
+// Line: 10
+
+public class C<T> where T : class
+{
+}
+
+class A
+{
+       public A (ref C<int> args)
+       {
+       }
+}
+
diff --git a/mcs/errors/cs0452-6.cs b/mcs/errors/cs0452-6.cs
new file mode 100644 (file)
index 0000000..3a7b4fd
--- /dev/null
@@ -0,0 +1,8 @@
+// CS0452: The type `int' must be a reference type in order to use it as type parameter `T' in the generic type or method `C<T>'
+// Line: 10
+
+public class C<T> where T : class
+{
+}
+
+delegate C<int> D ();
diff --git a/mcs/errors/cs0452-7.cs b/mcs/errors/cs0452-7.cs
new file mode 100644 (file)
index 0000000..264a976
--- /dev/null
@@ -0,0 +1,8 @@
+// CS0452: The type `int' must be a reference type in order to use it as type parameter `T' in the generic type or method `C<T>'
+// Line: 10
+
+public class C<T> where T : class
+{
+}
+
+delegate void D (C<int> arg);
diff --git a/mcs/errors/cs0452-8.cs b/mcs/errors/cs0452-8.cs
new file mode 100644 (file)
index 0000000..4082e45
--- /dev/null
@@ -0,0 +1,10 @@
+// CS0452: The type `ulong' must be a reference type in order to use it as type parameter `T' in the generic type or method `C<T>'
+// Line: 10
+
+public class C<T> where T : class
+{
+       public int this [params C<ulong>[] args] {
+               set {}
+       }
+}
+
diff --git a/mcs/errors/cs0453-6.cs b/mcs/errors/cs0453-6.cs
new file mode 100644 (file)
index 0000000..feaa3a1
--- /dev/null
@@ -0,0 +1,14 @@
+// CS0453: The type `string' must be a non-nullable value type in order to use it as type parameter `T' in the generic type or method `C<T>'
+// Line: 10
+
+public class C<T> where T : struct
+{
+}
+
+class A
+{
+       public C<string> Foo ()
+       {
+       }
+}
+
diff --git a/mcs/errors/cs0453-7.cs b/mcs/errors/cs0453-7.cs
new file mode 100644 (file)
index 0000000..1ad43f3
--- /dev/null
@@ -0,0 +1,14 @@
+// CS0453: The type `string' must be a non-nullable value type in order to use it as type parameter `T' in the generic type or method `C<T>'
+// Line: 10
+
+public class C<T> where T : struct
+{
+}
+
+class A
+{
+       public void Foo (C<string>[] args)
+       {
+       }
+}
+
diff --git a/mcs/errors/cs0619-56.cs b/mcs/errors/cs0619-56.cs
new file mode 100644 (file)
index 0000000..d26a147
--- /dev/null
@@ -0,0 +1,13 @@
+// CS0619: `A' is obsolete: `stop'
+// Line: 11
+
+using System;
+
+[Obsolete ("stop", true)]
+public class A
+{
+}
+
+public class C<T> where T : A
+{
+}
index f19eaab3e10a6f5bb2e8af00364ce3a0dcb47bc8..ed95af4d9f01abac35ebd14e065c8b04ab3a173b 100644 (file)
@@ -78,10 +78,6 @@ namespace Mono.CSharp
                                get { return tc; }
                        }
 
-                       public bool HasUnresolvedConstraints {
-                               get { return true; }
-                       }
-
                        public bool IsObsolete {
                                get { return tc.IsObsolete; }
                        }
@@ -1558,9 +1554,6 @@ namespace Mono.CSharp
                                                // TODO: passing `this' is wrong, should be base type iface instead
                                                TypeManager.CheckTypeVariance (iface_type, Variance.Covariant, this);
 
-                                               // TODO: Location is wrong, it should be unresolved iface expr location
-                                               ConstraintChecker.Check (this, iface_type, Location);
-
                                                if (((InflatedTypeSpec) iface_type).HasDynamicArgument () && !IsCompilerGenerated) {
                                                        Report.Error (1966, Location,
                                                                "`{0}': cannot implement a dynamic interface `{1}'",
@@ -1572,12 +1565,13 @@ namespace Mono.CSharp
                        }
 
                        if (base_type != null) {
+                               //
+                               // Run checks skipped during FullNamedExpression::ResolveAsType
+                               //
                                if (base_type_expr != null) {
                                        ObsoleteAttribute obsolete_attr = base_type.GetAttributeObsolete ();
                                        if (obsolete_attr != null && !IsObsolete)
                                                AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), base_type_expr.Location, Report);
-
-                                       ConstraintChecker.Check (this, base_type, base_type_expr.Location);
                                }
 
                                if (base_type.Interfaces != null) {
@@ -1597,12 +1591,6 @@ namespace Mono.CSharp
                                }
                        }
 
-                       if (type_params != null) {
-                               foreach (var tp in type_params) {
-                                       tp.CheckGenericConstraints ();
-                               }
-                       }
-
                        DefineContainerMembers (constants);
                        DefineContainerMembers (fields);
 
@@ -1826,13 +1814,31 @@ namespace Mono.CSharp
                                }
                        }
 
+                       // Run constraints check on all possible generic types
+                       if ((ModFlags & Modifiers.COMPILER_GENERATED) == 0) {
+                               if (base_type != null && base_type_expr != null) {
+                                       ConstraintChecker.Check (this, base_type, base_type_expr.Location);
+                               }
+
+                               if (iface_exprs != null) {
+                                       foreach (var iface_type in iface_exprs) {
+                                               if (iface_type == null)
+                                                       continue;
+
+                                               ConstraintChecker.Check (this, iface_type, Location);   // TODO: Location is wrong
+                                       }
+                               }
+                       }
+
                        if (all_tp_builders != null) {
                                int current_starts_index = CurrentTypeParametersStartIndex;
                                for (int i = 0; i < all_tp_builders.Length; i++) {
                                        if (i < current_starts_index) {
                                                TypeParameters[i].EmitConstraints (all_tp_builders [i]);
                                        } else {
-                                               CurrentTypeParameters [i - current_starts_index].Emit ();
+                                               var tp = CurrentTypeParameters [i - current_starts_index];
+                                               tp.CheckGenericConstraints (!IsObsolete);
+                                               tp.Emit ();
                                        }
                                }
                        }
index 6cbb42b6e00e08d95cf7411ddcc351be47c2675c..01cad1f2e8c26872939041e3b2ff624c6e44619f 100644 (file)
@@ -55,7 +55,6 @@ namespace Mono.CSharp
                bool IsObsolete { get; }
                bool IsUnsafe { get; }
                bool IsStatic { get; }
-               bool HasUnresolvedConstraints { get; }
 
                string GetSignatureForError ();
 
@@ -421,10 +420,6 @@ namespace Mono.CSharp
                        get { return (flags & Options.DoFlowAnalysis) != 0; }
                }
 
-               public bool HasUnresolvedConstraints {
-                       get { return false; }
-               }
-
                public bool IsInProbingMode {
                        get {
                                return (flags & Options.ProbingMode) != 0;
index fa0a1456251a62ea27e8d321426d246b243ae015..28e2ddff004665d103a7a0ecfe7ac6d45ef68338 100644 (file)
@@ -1708,7 +1708,7 @@ indexer_declaration
                if (type.Type != null && type.Type.Kind == MemberKind.Void)
                        report.Error (620, GetLocation ($3), "`{0}': indexer return type cannot be `void'", indexer.GetSignatureForError ());           
 
-               if (indexer.Parameters.IsEmpty) {
+               if (indexer.ParameterInfo.IsEmpty) {
                        report.Error (1551, GetLocation ($5), "Indexers must have at least one parameter");
                }
 
index 6d6d367bca4c7f93d718c65a31683eac2d39c390..6a28995c8810dde0c3ac0425e12d4242007fd6c6 100644 (file)
@@ -857,10 +857,6 @@ namespace Mono.CSharp {
                        get { return null; }
                }
 
-               public virtual bool HasUnresolvedConstraints {
-                       get { return false; }
-               }
-
                public bool IsObsolete {
                        get {
                                if (GetAttributeObsolete () != null)
@@ -904,6 +900,7 @@ namespace Mono.CSharp {
                        MissingDependency_Undetected = 1 << 4,
                        MissingDependency = 1 << 5,
                        HasDynamicElement = 1 << 6,
+                       ConstraintsChecked = 1 << 7,
 
                        IsAccessor = 1 << 9,            // Method is an accessor
                        IsGeneric = 1 << 10,            // Member contains type arguments
index 5e896c60b4be440a0e233d30e3383136cafc68d7..6c5eda6d5c363cf6abb87a89d0a2998c4365c3d7 100644 (file)
@@ -301,11 +301,14 @@ namespace Mono.CSharp {
                                        return_attributes = new ReturnParameter (this, InvokeBuilder.MethodBuilder, Location);
                                        Module.PredefinedAttributes.Dynamic.EmitAttribute (return_attributes.Builder, ReturnType.Type, Location);
                                }
+
+                               ConstraintChecker.Check (this, ReturnType.Type, ReturnType.Location);
                        }
 
                        Constructor.ParameterInfo.ApplyAttributes (this, Constructor.ConstructorBuilder);
                        Constructor.ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
 
+                       parameters.CheckConstraints (this);
                        parameters.ApplyAttributes (this, InvokeBuilder.MethodBuilder);
                        InvokeBuilder.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
 
index 8919fc1b7d29caea4404995c253ec0b04b8d4493..1b9646483fce61a8abf0fd94e48cbbaf4f3e8103 100644 (file)
@@ -2397,7 +2397,7 @@ namespace Mono.CSharp {
 
                        //
                        // Obsolete checks cannot be done when resolving base context as they
-                       // require type dependecies to be set but we are just resolving them
+                       // require type dependencies to be set but we are in process of resolving them
                        //
                        if (!(mc is TypeContainer.BaseContext)) {
                                ObsoleteAttribute obsolete_attr = type.GetAttributeObsolete ();
index 24818eba09527a4712cb95b885fb880d2dc1154a..1d4f88fd3a06ea762b547dc74c846687ff77f7f1 100644 (file)
@@ -237,6 +237,8 @@ namespace Mono.CSharp
                                Report.Error (625, Location, "`{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute", GetSignatureForError ());
                        }
 
+                       ConstraintChecker.Check (this, member_type, type_expr.Location);
+
                        base.Emit ();
                }
 
index b8a6f6e9e6dfd25f38123033eb5af30d1f30017c..06c9b55c401325531c68f18942081c214a6e60fd 100644 (file)
@@ -127,12 +127,23 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               public void CheckGenericConstraints (IMemberContext context)
+               public void CheckGenericConstraints (IMemberContext context, bool obsoleteCheck)
                {
                        foreach (var c in constraints) {
-                               if (c != null && c.Type != null) {
-                                       ConstraintChecker.Check (context, c.Type, c.Location);
+                               if (c == null)
+                                       continue;
+
+                               var t = c.Type;
+                               if (t == null)
+                                       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);
                                }
+
+                               ConstraintChecker.Check (context, t, c.Location);
                        }
                }
 
@@ -457,10 +468,10 @@ namespace Mono.CSharp {
                        builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
                }
 
-               public void CheckGenericConstraints ()
+               public void CheckGenericConstraints (bool obsoleteCheck)
                {
                        if (constraints != null)
-                               constraints.CheckGenericConstraints (this);
+                               constraints.CheckGenericConstraints (this, obsoleteCheck);
                }
 
                public TypeParameter CreateHoistedCopy (TypeContainer declaringType, TypeSpec declaringSpec)
@@ -1388,6 +1399,9 @@ namespace Mono.CSharp {
 
                        if (open_type.Kind == MemberKind.MissingType)
                                MemberCache = MemberCache.Empty;
+
+                       if ((open_type.Modifiers & Modifiers.COMPILER_GENERATED) != 0)
+                               state |= StateFlags.ConstraintsChecked;
                }
 
                #region Properties
@@ -1414,6 +1428,18 @@ namespace Mono.CSharp {
                        }
                }
 
+               //
+               // Used to cache expensive constraints validation on constructed types
+               //
+               public bool HasConstraintsChecked {
+                       get {
+                               return (state & StateFlags.ConstraintsChecked) != 0;
+                       }
+                       set {
+                               state = value ? state | StateFlags.ConstraintsChecked : state & ~StateFlags.ConstraintsChecked;
+                       }
+               }
+
                public override IList<TypeSpec> Interfaces {
                        get {
                                if (cache == null)
@@ -1931,9 +1957,12 @@ namespace Mono.CSharp {
                        return TypeManager.CSharpName (type);
                }
 
-               public override TypeSpec ResolveAsType (IMemberContext ec)
+               public override TypeSpec ResolveAsType (IMemberContext mc)
                {
-                       if (!args.Resolve (ec))
+                       if (eclass != ExprClass.Unresolved)
+                               return type;
+
+                       if (!args.Resolve (mc))
                                return null;
 
                        TypeSpec[] atypes = args.Arguments;
@@ -1941,14 +1970,22 @@ namespace Mono.CSharp {
                        //
                        // Now bind the parameters
                        //
-                       type = open_type.MakeGenericType (ec, atypes);
+                       var inflated = open_type.MakeGenericType (mc, atypes);
+                       type = inflated;
                        eclass = ExprClass.Type;
 
                        //
-                       // Check constraints when context is not method/base type
+                       // The constraints can be checked only when full type hierarchy is known
                        //
-                       if (!ec.HasUnresolvedConstraints)
-                               ConstraintChecker.Check (ec, type, loc);
+                       if (!inflated.HasConstraintsChecked && mc.Module.HasTypesFullyDefined) {
+                               var constraints = inflated.Constraints;
+                               if (constraints != null) {
+                                       var cc = new ConstraintChecker (mc);
+                                       if (cc.CheckAll (open_type, atypes, constraints, loc)) {
+                                               inflated.HasConstraintsChecked = true;
+                                       }
+                               }
+                       }
 
                        return type;
                }
@@ -1986,11 +2023,13 @@ namespace Mono.CSharp {
        {
                IMemberContext mc;
                bool ignore_inferred_dynamic;
+               bool recursive_checks;
 
                public ConstraintChecker (IMemberContext ctx)
                {
                        this.mc = ctx;
                        ignore_inferred_dynamic = false;
+                       recursive_checks = false;
                }
 
                #region Properties
@@ -2008,22 +2047,44 @@ namespace Mono.CSharp {
 
                //
                // Checks the constraints of open generic type against type
-               // arguments. Has to be called after all members have been defined
+               // arguments. This version is used for types which could not be
+               // checked immediatelly during construction because the type
+               // hierarchy was not yet fully setup (before Emit phase)
                //
                public static bool Check (IMemberContext mc, TypeSpec type, Location loc)
                {
-                       if ((type.Modifiers & Modifiers.COMPILER_GENERATED) != 0)
-                               return true;
+                       //
+                       // Check declaring type first if there is any
+                       //
+                       if (type.DeclaringType != null && !Check (mc, type.DeclaringType, loc))
+                               return false;
+
+                       while (type is ElementTypeSpec)
+                               type = ((ElementTypeSpec) type).Element;
 
                        if (type.Arity == 0)
                                return true;
 
-                       var gtype = (InflatedTypeSpec) type;
+                       var gtype = type as InflatedTypeSpec;
+                       if (gtype == null)
+                               return true;
+
                        var constraints = gtype.Constraints;
                        if (constraints == null)
                                return true;
 
-                       return new ConstraintChecker(mc).CheckAll (type.GetDefinition (), type.TypeArguments, constraints, loc);
+                       if (gtype.HasConstraintsChecked)
+                               return true;
+
+                       var cc = new ConstraintChecker (mc);
+                       cc.recursive_checks = true;
+
+                       if (cc.CheckAll (gtype.GetDefinition (), type.TypeArguments, constraints, loc)) {
+                               gtype.HasConstraintsChecked = true;
+                               return true;
+                       }
+
+                       return false;
                }
 
                //
@@ -2036,7 +2097,14 @@ namespace Mono.CSharp {
                                if (ignore_inferred_dynamic && targs[i].BuiltinType == BuiltinTypeSpec.Type.Dynamic)
                                        continue;
 
-                               if (!CheckConstraint (context, targs [i], tparams [i], loc))
+                               var targ = targs[i];
+                               if (!CheckConstraint (context, targ, tparams [i], loc))
+                                       return false;
+
+                               if (!recursive_checks)
+                                       continue;
+
+                               if (!Check (mc, targ, loc))
                                        return false;
                        }
 
index a31d6be14d4caabfc0bbcf09525afded281b190f..90f13cd98f32e1344f6a395e742b0102fd9ee8a8 100644 (file)
@@ -134,6 +134,15 @@ namespace Mono.CSharp {
                        get { return "M:"; }
                }
 
+               public override void Emit ()
+               {
+                       if ((ModFlags & Modifiers.COMPILER_GENERATED) == 0) {
+                               parameters.CheckConstraints (this);
+                       }
+
+                       base.Emit ();
+               }
+
                public override bool EnableOverloadChecks (MemberCore overload)
                {
                        if (overload is MethodCore) {
@@ -668,11 +677,14 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (MethodData != null)
-                               MethodData.Emit (Parent);
+                       if (type_expr != null)
+                               ConstraintChecker.Check (this, member_type, type_expr.Location);
 
                        base.Emit ();
 
+                       if (MethodData != null)
+                               MethodData.Emit (Parent);
+
                        Block = null;
                        MethodData = null;
                }
@@ -858,23 +870,6 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override bool HasUnresolvedConstraints {
-                       get {
-                               if (CurrentTypeParameters == null)
-                                       return false;
-
-                               // When overriding base method constraints are fetched from
-                               // base method but to find it we have to resolve parameters
-                               // to find exact base method match
-                               if (IsExplicitImpl || (ModFlags & Modifiers.OVERRIDE) != 0)
-                                       return base_method == null;
-
-                               // Even for non-override generic method constraints check has to be
-                               // delayed after all constraints are resolved
-                               return true;
-                       }
-               }
-
                public TypeParameterSpec[] TypeParameters {
                        get {
                                // TODO: Cache this
@@ -1212,15 +1207,9 @@ namespace Mono.CSharp {
                                }
 
                                if (CurrentTypeParameters != null) {
-                                       ConstraintChecker.Check (this, member_type, type_expr.Location);
-
-                                       for (int i = 0; i < parameters.Count; ++i) {
-                                               ConstraintChecker.Check (this, parameters.Types[i], Location); // TODO: Location is wrong
-                                       }
-
                                        for (int i = 0; i < CurrentTypeParameters.Length; ++i) {
                                                var tp = CurrentTypeParameters [i];
-                                               tp.CheckGenericConstraints ();
+                                               tp.CheckGenericConstraints (false);
                                                tp.Emit ();
                                        }
                                }
@@ -1568,6 +1557,7 @@ namespace Mono.CSharp {
                                OptAttributes.Emit ();
 
                        base.Emit ();
+                       parameters.ApplyAttributes (this, ConstructorBuilder);
 
                        //
                        // If we use a "this (...)" constructor initializer, then
@@ -1599,8 +1589,6 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       parameters.ApplyAttributes (this, ConstructorBuilder);
-
                        SourceMethod source = SourceMethod.Create (Parent, ConstructorBuilder, block);
 
                        if (block != null) {
index 7afb8f12158f6fac3ecd400061ea8115837e46be..fdafbee39f8dd16f59316d934e4c9cd6a9597045 100644 (file)
@@ -288,9 +288,6 @@ namespace Mono.CSharp {
                        if (best == null)
                                return null;
 
-//                     if ((best.Modifiers & Modifiers.INTERNAL) != 0 && !best.MemberDefinition.IsInternalAsPublic (ctx.Module.DeclaringAssembly))
-//                             return null;
-
                        te = new TypeExpression (best, Location.Null);
 
                        // TODO MemberCache: Cache more
@@ -1106,11 +1103,6 @@ namespace Mono.CSharp {
                        get { return SlaveDeclSpace.CurrentTypeParameters; }
                }
 
-               // FIXME: It's false for expression types
-               public bool HasUnresolvedConstraints {
-                       get { return true; }
-               }
-
                public bool IsObsolete {
                        get { return SlaveDeclSpace.IsObsolete; }
                }
index cb768e1d82b8c1919f9fcebff986478f17445227..b6a89ee5cfb346b054598f8172af28c070a1df96 100644 (file)
@@ -1007,6 +1007,17 @@ namespace Mono.CSharp {
                                null);
                }
 
+               public void CheckConstraints (IMemberContext mc)
+               {
+                       foreach (Parameter p in parameters) {
+                               //
+                               // It's null for compiler generated types or special types like __arglist
+                               //
+                               if (p.TypeExpression != null)
+                                       ConstraintChecker.Check (mc, p.Type, p.TypeExpression.Location);
+                       }
+               }
+
                //
                // Returns non-zero value for equal CLS parameter signatures
                //
index 21182e8e9a4692c6f1e74ba8467d41d8880992d3..c5fea5c11104d5493489fc5b83c21d71eb53df98 100644 (file)
@@ -668,6 +668,8 @@ namespace Mono.CSharp
                                Module.PredefinedAttributes.Dynamic.EmitAttribute (PropertyBuilder, member_type, Location);
                        }
 
+                       ConstraintChecker.Check (this, member_type, type_expr.Location);
+
                        first.Emit (Parent);
                        if (AccessorSecond != null)
                                AccessorSecond.Emit (Parent);
@@ -1300,6 +1302,8 @@ namespace Mono.CSharp
                                OptAttributes.Emit ();
                        }
 
+                       ConstraintChecker.Check (this, member_type, type_expr.Location);
+
                        Add.Emit (Parent);
                        Remove.Emit (Parent);
 
@@ -1469,6 +1473,22 @@ namespace Mono.CSharp
                        this.parameters = parameters;
                }
 
+               #region Properties
+
+               AParametersCollection IParametersMember.Parameters {
+                       get {
+                               return parameters;
+                       }
+               }
+
+               public ParametersCompiled ParameterInfo {
+                       get {
+                               return parameters;
+                       }
+               }
+
+               #endregion
+
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Type == pa.IndexerName) {
@@ -1547,6 +1567,13 @@ namespace Mono.CSharp
                        return base.EnableOverloadChecks (overload);
                }
 
+               public override void Emit ()
+               {
+                       parameters.CheckConstraints (this);
+
+                       base.Emit ();
+               }
+
                public override string GetSignatureForError ()
                {
                        StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
@@ -1565,18 +1592,6 @@ namespace Mono.CSharp
                        return base.GetSignatureForDocumentation () + parameters.GetSignatureForDocumentation ();
                }
 
-               public AParametersCollection Parameters {
-                       get {
-                               return parameters;
-                       }
-               }
-
-               public ParametersCompiled ParameterInfo {
-                       get {
-                               return parameters;
-                       }
-               }
-
                protected override bool VerifyClsCompliance ()
                {
                        if (!base.VerifyClsCompliance ())
index 260259037c5f1bc1ef498821d224653b6d570767..a5be3f835a4a8deb13bc5d30b4b26538c748666d 100644 (file)
@@ -225,6 +225,10 @@ namespace Mono.CSharp
                        }
                }
 
+               public bool HasTypesFullyDefined {
+                       get; set;
+               }
+
                //
                // Returns module global:: namespace
                //
@@ -418,6 +422,8 @@ namespace Mono.CSharp
                                        throw new InternalErrorException (tc, e);
                                }
                        }
+
+                       HasTypesFullyDefined = true;
                }
 
                public override void Emit ()