Permalink
Browse files

Better type parameter value type conversion checks

  • Loading branch information...
1 parent 3e03af5 commit bf9a580867cd573a398ed5c3ea5668c57e5b9b9b @marek-safar marek-safar committed Oct 31, 2011
Showing with 45 additions and 35 deletions.
  1. +22 −0 mcs/errors/cs1061-12.cs
  2. +1 −1 mcs/mcs/expression.cs
  3. +18 −25 mcs/mcs/generic.cs
  4. +1 −6 mcs/mcs/method.cs
  5. +3 −3 mcs/tests/gtest-564.cs
View
@@ -0,0 +1,22 @@
+// CS1061: Type `U2' does not contain a definition for `Test' and no extension method `Test' of type `U2' could be found (are you missing a using directive or an assembly reference?)
+// Line: 20
+
+interface I<T>
+{
+ void Foo<U> (U u) where U : T;
+}
+
+struct S
+{
+ public void Test ()
+ {
+ }
+}
+
+class Test : I<S>
+{
+ void I<S>.Foo<U2> (U2 u2)
+ {
+ u2.Test ();
+ }
+}
View
@@ -5544,7 +5544,7 @@ protected override Expression DoResolve (ResolveContext ec)
// Check whether the type of type parameter can be constructed. BaseType can be a struct for method overrides
// where type parameter constraint is inflated to struct
//
- if ((tparam.SpecialConstraint & (SpecialConstraint.Struct | SpecialConstraint.Constructor)) == 0 && !tparam.BaseType.IsStruct) {
+ if ((tparam.SpecialConstraint & (SpecialConstraint.Struct | SpecialConstraint.Constructor)) == 0 && !TypeSpec.IsValueType (tparam)) {
ec.Report.Error (304, loc,
"Cannot create an instance of the variable type `{0}' because it does not have the new() constraint",
TypeManager.CSharpName (type));
View
@@ -801,7 +801,17 @@ public TypeParameterSpec (int index, ITypeDefinition definition, SpecialConstrai
// class A : B<int> { override void Foo<U> () {} }
// class B<T> { virtual void Foo<U> () where U : T {} }
//
- return HasSpecialStruct || TypeSpec.IsValueType (BaseType);
+ if (HasSpecialStruct)
+ return true;
+
+ if (targs != null) {
+ foreach (var ta in targs) {
+ if (TypeSpec.IsValueType (ta))
+ return true;
+ }
+ }
+
+ return false;
}
}
@@ -846,21 +856,6 @@ public TypeParameterSpec (int index, ITypeDefinition definition, SpecialConstrai
#endregion
- public void ChangeTypeArgumentToBaseType (int index)
- {
- BaseType = targs [index];
- if (targs.Length == 1) {
- targs = null;
- } else {
- var copy = new TypeSpec[targs.Length - 1];
- if (index > 0)
- Array.Copy (targs, copy, index);
-
- Array.Copy (targs, index + 1, copy, index, targs.Length - index - 1);
- targs = copy;
- }
- }
-
public string DisplayDebugInfo ()
{
var s = GetSignatureForError ();
@@ -2322,16 +2317,14 @@ bool CheckConversion (IMemberContext mc, MemberSpec context, TypeSpec atype, Typ
if (atype.IsGenericParameter) {
var tps = (TypeParameterSpec) atype;
- if (Convert.ImplicitTypeParameterConversion (null, tps, ttype) != null)
- return true;
+ if (tps.TypeArguments != null) {
+ foreach (var targ in tps.TypeArguments) {
+ if (TypeSpecComparer.Override.IsEqual (targ, ttype))
+ return true;
+ }
+ }
- //
- // LAMESPEC: Identity conversion with inflated type parameter
- // It's not clear from the spec what rule should apply to inherited
- // inflated type parameter. The specification allows only type parameter
- // conversion but that's clearly not enough
- //
- if (tps.HasTypeConstraint && tps.BaseType == ttype)
+ if (Convert.ImplicitTypeParameterConversion (null, tps, ttype) != null)
return true;
} else if (TypeSpec.IsValueType (atype)) {
View
@@ -9,6 +9,7 @@
//
// Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
// Copyright 2004-2008 Novell, Inc
+// Copyright 2011 Xamarin Inc.
//
using System;
@@ -1140,12 +1141,6 @@ protected virtual void DefineTypeParameters ()
Constraints.CheckConflictingInheritedConstraint (local_tparam, ta, this, Location);
}
-
- // TODO: Better logic is needed to select new best base type for length > 1
- if (!local_tparam.HasTypeConstraint && local_tparam_targs.Length == 1 && !local_tparam_targs[0].IsGenericParameter) {
- local_tparam.TypeArguments = null;
- local_tparam.BaseType = local_tparam_targs[0];
- }
}
continue;
View
@@ -34,15 +34,15 @@ public static int Main ()
{
var m = typeof (C1).GetMethod ("Test");
var ta = m.GetGenericArguments ()[0].GetGenericParameterConstraints ();
- if (ta.Length != 1)
+ if (ta.Length != 2)
return 1;
m = typeof (C2).GetMethod ("Test");
ta = m.GetGenericArguments ()[0].GetGenericParameterConstraints ();
if (ta.Length != 1)
- return 1;
+ return 2;
Console.WriteLine ("ok");
return 0;
}
-}
+}

0 comments on commit bf9a580

Please sign in to comment.