2003-09-22 Martin Baulig <martin@ximian.com>
authorMartin Baulig <martin@novell.com>
Mon, 22 Sep 2003 00:07:07 +0000 (00:07 -0000)
committerMartin Baulig <martin@novell.com>
Mon, 22 Sep 2003 00:07:07 +0000 (00:07 -0000)
* generic.cs (ConstructedType.ResolveAsTypeCheck): Check whether
all type arguments meet their constraints.

svn path=/trunk/mcs/; revision=18252

mcs/gmcs/ChangeLog
mcs/gmcs/generic.cs

index 66d1a7dbec6c04a94100ded9edc1a5e213ed4bd2..5546eef828d7b86ccaed2c0532c575eeba45c559 100755 (executable)
@@ -1,3 +1,8 @@
+2003-09-22  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.ResolveAsTypeCheck): Check whether
+       all type arguments meet their constraints.
+
 2003-09-19  Martin Baulig  <martin@ximian.com>
 
        * decl.cs (MemberCache.SetupCacheForInterface): Take a
index b57aaa2bd3ec314f5cdd2e8674c8248dad029878..26c84ea1f3d1a2eb9e86533a93754333d52b88a5 100644 (file)
@@ -263,8 +263,9 @@ namespace Mono.CSharp {
        
        public class ConstructedType : Expression {
                Expression container_type;
-               string name;
+               string name, full_name;
                TypeArguments args;
+               Type[] gen_params;
                
                public ConstructedType (string name, TypeArguments args, Location l)
                {
@@ -273,6 +274,8 @@ namespace Mono.CSharp {
                        this.name = name;
                        this.args = args;
                        eclass = ExprClass.Type;
+
+                       full_name = name + "<" + args.ToString () + ">";
                }
 
                public override Expression DoResolve (EmitContext ec)
@@ -286,6 +289,38 @@ namespace Mono.CSharp {
                        return new SimpleName (name, loc).DoResolve (ec);
                }
 
+               protected bool CheckConstraints (int index)
+               {
+                       Type atype = args.Arguments [index];
+                       Type ptype = gen_params [index];
+
+                       //
+                       // First, check parent class.
+                       //
+                       if ((ptype.BaseType != atype.BaseType) &&
+                           !atype.BaseType.IsSubclassOf (ptype.BaseType)) {
+                               Report.Error (-219, loc, "Cannot create constructed type `{0}': " +
+                                             "type argument `{1}' must derive from `{2}'.",
+                                             full_name, atype, ptype.BaseType);
+                               return false;
+                       }
+
+                       //
+                       // Now, check the interfaces.
+                       //
+                       foreach (Type itype in ptype.GetInterfaces ()) {
+                               if (TypeManager.ImplementsInterface (atype, itype))
+                                       continue;
+
+                               Report.Error (-219, loc, "Cannot create constructed type `{0}: " +
+                                             "type argument `{1}' must implement interface `{2}'.",
+                                             full_name, atype, itype);
+                               return false;
+                       }
+
+                       return true;
+               }
+
                public override Expression ResolveAsTypeStep (EmitContext ec)
                {
                        if (args.Resolve (ec) == false)
@@ -301,7 +336,7 @@ namespace Mono.CSharp {
 
                        Type gt = resolved.Type.GetGenericTypeDefinition ();
 
-                       Type[] gen_params = gt.GetGenericParameters ();
+                       gen_params = gt.GetGenericParameters ();
                        if (args.Arguments.Length != gen_params.Length) {
                                Report.Error (-217, loc, "Generic type `" + gt.Name + "' takes " +
                                              gen_params.Length + " type parameters, but specified " +
@@ -309,6 +344,11 @@ namespace Mono.CSharp {
                                return null;
                        }
 
+                       for (int i = 0; i < gen_params.Length; i++) {
+                               if (!CheckConstraints (i))
+                                       return null;
+                       }
+
                        //
                        // Now bind the parameters.
                        //
@@ -326,7 +366,7 @@ namespace Mono.CSharp {
 
                public override string ToString ()
                {
-                       return name + "<" + args.ToString () + ">";
+                       return full_name;
                }
        }
 }