Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/mcs
diff options
context:
space:
mode:
authorMarek Safar <marek.safar@gmail.com>2015-09-07 17:08:58 +0300
committerMarek Safar <marek.safar@gmail.com>2015-09-07 17:11:59 +0300
commit5e81ed1e03581885585e819c3dc14e60455cf42d (patch)
tree2526f867e8add20c35289ee202473f5dc039ce8f /mcs
parent9dd35ce4a56b018ae83f0681d0b93e2ac1c00d42 (diff)
[mcs] Consider whole hierarchy of inherited type arguments inflated via base type. Fixes #33669
Diffstat (limited to 'mcs')
-rw-r--r--mcs/mcs/generic.cs40
-rw-r--r--mcs/tests/gtest-634.cs27
-rw-r--r--mcs/tests/ver-il-net_4_x.xml31
3 files changed, 79 insertions, 19 deletions
diff --git a/mcs/mcs/generic.cs b/mcs/mcs/generic.cs
index b4b98f067a8..e63e999dc79 100644
--- a/mcs/mcs/generic.cs
+++ b/mcs/mcs/generic.cs
@@ -649,10 +649,10 @@ namespace Mono.CSharp {
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 ());
@@ -1334,12 +1334,26 @@ namespace Mono.CSharp {
{
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) {
@@ -1347,25 +1361,13 @@ namespace Mono.CSharp {
}
}
+ //
+ // 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;
- TypeSpec b_type;
- if (tps != null) {
- b_type = tps.GetEffectiveBase ();
- ifaces = tps.InterfacesDefined;
- } else {
- b_type = ta;
- ifaces = ta.Interfaces;
- }
-
- //
- // Don't add base type which was inflated from base constraints but it's not valid
- // in C# context
- //
- if (b_type != null && b_type.BuiltinType != BuiltinTypeSpec.Type.Object && b_type.BuiltinType != BuiltinTypeSpec.Type.ValueType && !b_type.IsStructOrEnum)
- cache.AddBaseType (b_type);
+ var ifaces = tps == null ? ta.Interfaces : tps.InterfacesDefined;
if (ifaces != null) {
foreach (var iface_type in ifaces) {
diff --git a/mcs/tests/gtest-634.cs b/mcs/tests/gtest-634.cs
new file mode 100644
index 00000000000..b078d28e6a1
--- /dev/null
+++ b/mcs/tests/gtest-634.cs
@@ -0,0 +1,27 @@
+using System;
+
+public abstract class ThingWithOrganizationId
+{
+ public Guid OrganizationId;
+}
+
+public class Thing : ThingWithOrganizationId
+{
+}
+
+public abstract class BaseService<TConstraint>
+{
+ public abstract void Save<T> (T newThing) where T : TConstraint;
+}
+
+public class DerivedService:BaseService<Thing>
+{
+ public override void Save<TThing>(TThing newThing)
+ {
+ Console.WriteLine (newThing.OrganizationId);
+ }
+
+ static void Main ()
+ {
+ }
+} \ No newline at end of file
diff --git a/mcs/tests/ver-il-net_4_x.xml b/mcs/tests/ver-il-net_4_x.xml
index 9cfd1240b1a..0ea541bffb6 100644
--- a/mcs/tests/ver-il-net_4_x.xml
+++ b/mcs/tests/ver-il-net_4_x.xml
@@ -19688,6 +19688,37 @@
</method>
</type>
</test>
+ <test name="gtest-634.cs">
+ <type name="ThingWithOrganizationId">
+ <method name="Void .ctor()" attrs="6276">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="Thing">
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="BaseService`1[TConstraint]">
+ <method name="Void Save[T](T)" attrs="1478">
+ <size>0</size>
+ </method>
+ <method name="Void .ctor()" attrs="6276">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="DerivedService">
+ <method name="Void Save[TThing](TThing)" attrs="198">
+ <size>23</size>
+ </method>
+ <method name="Void Main()" attrs="145">
+ <size>2</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="gtest-anontype-01.cs">
<type name="Test">
<method name="Int32 Main()" attrs="150">