This commit is contained in:
Ivan Bondarev 2023-12-28 11:24:30 +01:00
parent 9721cf3c67
commit 0e3a3c232e
2 changed files with 35 additions and 2 deletions

22
TestSuite/where22.pas Normal file
View file

@ -0,0 +1,22 @@
type
t1<TSelf> = interface
where TSelf: t1<TSelf>;
function f: integer;
end;
//Ошибка: Невозможно инстанцировать, так как тип TSelf не реализует интерфейс t1<TSelf>
t2<TSelf> = interface(t1<TSelf>)
where TSelf: t2<TSelf>;
// А если так то работает:
// where TSelf: t1<TSelf>, t2<TSelf>;
end;
TClass = class(t2<TClass>)
public function f: integer;
begin
Result := 1;
end;
end;
begin
var obj := new TClass;
assert(obj.f = 1);
end.

View file

@ -620,7 +620,7 @@ namespace PascalABCCompiler.TreeRealization
if (interf_original_generic != null && interf_original_generic == base_original_generic)
{
// Нам нужно два original_generic as compiled_type_node и два instance_params
//if (ctcgi != null) // по идее это всегда так! потому что cgitn - compiled - поэтому закомментировал SSM 14/02/23
// теперь надо проверить параметры на ковариантность - все
var n = base_instance_params.Count;
@ -632,7 +632,7 @@ namespace PascalABCCompiler.TreeRealization
if (n != n1)
impl = false;
else
for (int i=0; i<n; i++)
for (int i = 0; i < n; i++)
{
// ctcgi.compiled_type - это System.Type
if ((interf_compiled_type.GetGenericArguments()[i].GenericParameterAttributes & System.Reflection.GenericParameterAttributes.Covariant) != 0)
@ -665,6 +665,17 @@ namespace PascalABCCompiler.TreeRealization
break;
}
}
else if (interf is common_generic_instance_type_node cictn && base_class is common_generic_instance_type_node cbctn)
{
foreach (type_node impltn in cictn.ImplementingInterfaces)
{
if (is_type_or_original_generics_equal(impltn, cbctn))
{
implements = true;
break;
}
}
}
else if (interf is compiled_type_node ictn && base_class is compiled_type_node bctn)
{
if (ictn.compiled_type.AssemblyQualifiedName != null && ictn.compiled_type.AssemblyQualifiedName == bctn.compiled_type.AssemblyQualifiedName)