diff --git a/TestSuite/generics21.pas b/TestSuite/generics21.pas new file mode 100644 index 000000000..7b7289e45 --- /dev/null +++ b/TestSuite/generics21.pas @@ -0,0 +1,40 @@ +type + t1=class end; + t2=class(t1) end; + t3 = class(t2) end; + +var i: integer; + +procedure p1(self:t1); +begin + i := 1; +end; +procedure p2(self:t1); extensionmethod; +begin + i := 2; +end; +procedure p3(self:t1); extensionmethod; +begin + i := 2; +end; +procedure p3(self:t3); extensionmethod; +begin + i := 3; +end; +begin + var a := new t2; + p1(a); + assert(i = 1); + a.p2; + assert(i = 2); + var b := new t3; + i := 0; + p1(b); + assert(i = 1); + b.p2; + assert(i = 2); + b.p3; + assert(i = 3); + a.p3; + assert(i = 2); +end. \ No newline at end of file diff --git a/TreeConverter/TreeRealization/generics.cs b/TreeConverter/TreeRealization/generics.cs index 92dbe3126..a2b210935 100644 --- a/TreeConverter/TreeRealization/generics.cs +++ b/TreeConverter/TreeRealization/generics.cs @@ -1183,9 +1183,19 @@ namespace PascalABCCompiler.TreeRealization type_node fact_type_converted; //Сюда будет записан фактический тип или интерфейс, к которому он приводится if (!fact_type.is_generic_type_instance || formal_type.original_generic != fact_type.original_generic) { - if (!formal_type.IsInterface) goto eq_cmp; + //if (!formal_type.IsInterface) goto eq_cmp; fact_type_converted = null; - if (fact_type.ImplementingInterfaces != null) + type_node base_type = fact_type.base_type; + while (base_type != null) + { + if (base_type.original_generic == formal_type.original_generic) + { + fact_type_converted = base_type; + break; + } + base_type = base_type.base_type; + } + if (fact_type.ImplementingInterfaces != null && fact_type_converted == null) foreach (type_node ti in fact_type.ImplementingInterfaces) { if (ti.original_generic == formal_type.original_generic)