This commit is contained in:
Ivan Bondarev 2023-12-27 12:42:58 +01:00
parent 9f1d383ff6
commit a1867f0421
2 changed files with 65 additions and 1 deletions

35
TestSuite/where20.pas Normal file
View file

@ -0,0 +1,35 @@
type
c1<T1,T2> = class
// Если объявить сначала "where T1" - тоже должно работать
where T2: IComparable<T1>;
where T1: T2;
function f1(o: T1): integer;
begin
//Ошибка: Неизвестное имя 'CompareTo'
Result := o.CompareTo(o);
end;
end;
c2<T1,T2> = class
// Если объявить сначала "where T1" - тоже должно работать
where T2: IComparable<T1>;
where T1: T2;
function f1(o: T1): integer;
begin
//Ошибка: Неизвестное имя 'CompareTo'
Result := o.CompareTo(o);
end;
end;
begin
var a := new c1<string,string>;
assert(a.f1('abc') = 0);
var b := new c2<string,string>;
assert(b.f1('abc') = 0);
end.

View file

@ -4100,7 +4100,18 @@ namespace PascalABCCompiler.TreeConverter
(ctn.Scope as SymbolTable.InterfaceScope).TopInterfaceScopeArray =
interf_scopes.ToArray();
}
private void InitInterfaceScope(common_type_node ctn, List<SemanticTree.ITypeNode> interfaces)
{
List<SymbolTable.Scope> interf_scopes = new List<SymbolTable.Scope>(interfaces.Count);
foreach (type_node tnode in interfaces)
{
interf_scopes.Add(tnode.Scope);
}
(ctn.Scope as SymbolTable.InterfaceScope).TopInterfaceScopeArray =
interf_scopes.ToArray();
}
private void visit_function_realizations(SyntaxTree.declarations _decls)
{
foreach (SyntaxTree.declaration sd in _decls.defs)
@ -12969,6 +12980,16 @@ namespace PascalABCCompiler.TreeConverter
ind++;
}
}
foreach (common_type_node ctn in used_types)
{
if (ctn.base_type != null && ctn.base_type.is_generic_parameter && ctn.base_type.ImplementingInterfaces != null && ctn.base_type.ImplementingInterfaces.Count > 0)
{
foreach (type_node tn in ctn.ImplementingInterfaces)
{
type_table.AddInterface(ctn, tn, null);
}
}
}
context.EndSkipGenericInstanceChecking();
}
@ -13071,6 +13092,14 @@ namespace PascalABCCompiler.TreeConverter
AddError(get_location(specificators[i]), "STATIC_CLASS_CAN_NOT_BE_USED_AS_PARENT_SPECIFICATOR");
check_cycle_inheritance(param, spec_type);
param.SetBaseType(spec_type);
if (spec_type.is_generic_parameter && spec_type.ImplementingInterfaces.Count > 0)
{
foreach (type_node tn in spec_type.ImplementingInterfaces)
{
used_interfs.Add(tn, tn);
type_table.AddInterface(param, tn, get_location(specificators[i]));
}
}
base_is_enum = spec_type == SystemLibrary.SystemLibrary.enum_base_type;
// Чтобы в секции where override метода можно было указать class вместо конкретного типа
// Иначе CLR падает с TypeLoadException