From: Marek Safar Date: Mon, 10 Oct 2011 17:39:42 +0000 (+0100) Subject: Populate already inflated type instances with defined interfaces. Fixes #1389 X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=c216dd34710e586320f8defb7bdb0ffac9161028;p=mono.git Populate already inflated type instances with defined interfaces. Fixes #1389 --- diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs index d3dc57e2d91..4ccb423184b 100644 --- a/mcs/mcs/class.cs +++ b/mcs/mcs/class.cs @@ -3,12 +3,13 @@ // // Authors: Miguel de Icaza (miguel@gnu.org) // Martin Baulig (martin@ximian.com) -// Marek Safar (marek.safar@seznam.cz) +// Marek Safar (marek.safar@gmail.com) // // Dual licensed under the terms of the MIT X11 or GNU GPL // // Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com) // Copyright 2004-2008 Novell, Inc +// Copyright 2011 Xamarin, Inc (http://www.xamarin.com) // using System; @@ -1223,7 +1224,7 @@ namespace Mono.CSharp if (iface_type == null) continue; - if (!spec.AddInterface (iface_type)) + if (!spec.AddInterfaceDefined (iface_type)) continue; TypeBuilder.AddInterfaceImplementation (iface_type.GetMetaInfo ()); @@ -1239,7 +1240,7 @@ namespace Mono.CSharp var base_ifaces = new List (iface_type.Interfaces); for (int i = 0; i < base_ifaces.Count; ++i) { var ii_iface_type = base_ifaces[i]; - if (spec.AddInterface (ii_iface_type)) { + if (spec.AddInterfaceDefined (ii_iface_type)) { TypeBuilder.AddInterfaceImplementation (ii_iface_type.GetMetaInfo ()); if (ii_iface_type.Interfaces != null) diff --git a/mcs/mcs/typespec.cs b/mcs/mcs/typespec.cs index 5c8455224da..d25de6614b5 100644 --- a/mcs/mcs/typespec.cs +++ b/mcs/mcs/typespec.cs @@ -340,6 +340,34 @@ namespace Mono.CSharp return false; } + // + // Special version used during type definition + // + public bool AddInterfaceDefined (TypeSpec iface) + { + if (!AddInterface (iface)) + return false; + + // + // We can get into a situation where a type is inflated before + // its interfaces are resoved. Consider this situation + // + // class A : X>, IFoo {} + // + // When resolving base class of X`1 we inflate context type A`1 + // All this happens before we even hit IFoo resolve. Without + // additional expansion any inside usage of A would miss IFoo + // interface because it comes from early inflated TypeSpec + // + if (inflated_instances != null) { + foreach (var inflated in inflated_instances) { + inflated.Value.AddInterface (iface); + } + } + + return true; + } + public AttributeUsageAttribute GetAttributeUsage (PredefinedAttribute pa) { if (Kind != MemberKind.Class) diff --git a/mcs/tests/gtest-562.cs b/mcs/tests/gtest-562.cs new file mode 100644 index 00000000000..9cd8d921c90 --- /dev/null +++ b/mcs/tests/gtest-562.cs @@ -0,0 +1,56 @@ +interface IFoo { } + +abstract class A +{ + public T Value; +} + +class B : A>, IFoo +{ + public void Test () + { + IFoo foo = this; + Value = this; + } +} + +class C : A.N>, IFoo +{ + public void Test () + { + IFoo foo = this; + Value = new N (); + } + + public class N + { + } +} + +class D : A> +{ + public void Test () + { + Value = new D (); + } +} + +class E : IFoo where U : A> +{ + public void Test (U u) + { + IFoo foo = u.Value; + } +} + +static class Application +{ + public static int Main () + { + new B().Test (); + new C().Test (); + new D().Test (); + + return 0; + } +} \ No newline at end of file diff --git a/mcs/tests/ver-il-net_4_5.xml b/mcs/tests/ver-il-net_4_5.xml index f6f0f1f8a11..084c44582ea 100644 --- a/mcs/tests/ver-il-net_4_5.xml +++ b/mcs/tests/ver-il-net_4_5.xml @@ -17389,6 +17389,55 @@ + + + + 7 + + + + + 10 + + + 7 + + + + + 14 + + + 7 + + + + + 7 + + + + + 12 + + + 7 + + + + + 32 + + + + + 13 + + + 7 + + +