fix #2881
This commit is contained in:
Ivan Bondarev 2024-04-01 12:31:21 +02:00
parent 23b9ce9d37
commit ba0b0f8c39
4 changed files with 75 additions and 1 deletions

17
TestSuite/delegates23.pas Normal file
View file

@ -0,0 +1,17 @@
var i: integer;
procedure p0(p: byte->());
begin
Inc(i);
end;
procedure p1<T>(o: T);
begin
Inc(i);
end;
begin
p0(p1&<byte>);
//Ошибка: Нельзя преобразовать тип procedure(o: T) к Action<byte>
p0(p1);
assert(i = 2);
end.

12
TestSuite/delegates24.pas Normal file
View file

@ -0,0 +1,12 @@
begin
var i := 0;
//Ошибка: Неизвестное имя 'procedure()'
var d: procedure(p: procedure);
// Если убрать присваивание, ошибка выше пропадает
d := p ->
begin
p;
end;
d(() -> begin Inc(i) end);
assert(i = 1);
end.

View file

@ -1204,13 +1204,44 @@ namespace PascalABCCompiler.TreeConverter
{
//issue #2161 - SSM 12.03.2020
//issue #348
if (formal_param_type == SystemLibrary.SystemLibrary.object_type && factparams[i].type is delegated_methods)
if ((formal_param_type == SystemLibrary.SystemLibrary.object_type || formal_param_type.IsDelegate) && factparams[i].type is delegated_methods)
{
possible_type_convertions ptci = new possible_type_convertions();
ptci.first = null;
ptci.second = null;
if (formal_param_type.instance_params != null && formal_param_type.instance_params.Count > 0)
{
var fn = (factparams[i].type as delegated_methods).proper_methods[0].simple_function_node;
if (fn.is_generic_function)
{
var fn_instance = fn.get_instance(formal_param_type.instance_params, true, factparams[i].location);
delegated_methods dm = new delegated_methods();
if (fn is common_namespace_function_node)
dm.proper_methods.AddElement(new common_namespace_function_call(fn_instance as common_namespace_function_node, factparams[i].location));
factparams[i].type = dm;
}
else if (!is_alone_method_defined)
return null;
}
else if (!is_alone_method_defined && formal_param_type.IsDelegate)
return null;
ptci.from = factparams[i].type;
ptci.to = formal_param_type;
if (formal_param_type.IsDelegate)
{
var ttc = type_table.get_convertions(formal_param_type, factparams[i].type);
if (ttc.first == null)
{
if (is_alone_method_defined) // если мы сюда попали, то ошибка более явная
{
error = new CanNotConvertTypes(factparams[i], factparams[i].type, formal_param_type, locg);
return null;
}
else
return null;
}
}
tc.AddElement(ptci);
factparams[i] = syntax_tree_visitor.CreateDelegateCall((factparams[i].type as delegated_methods).proper_methods[0]);
//return tc;

View file

@ -1144,6 +1144,20 @@ namespace PascalABCCompiler.TreeRealization
}
}
}
else if (to is delegated_methods)
{
var proper_meth = (to as delegated_methods).proper_methods[0].simple_function_node;
if (dii.parameters.Count == proper_meth.parameters.Count)
{
//ms100 error fixed (DS)
bool eq = TreeConverter.convertion_data_and_alghoritms.function_eq_params_and_result(dii.invoke_method, proper_meth);
if (eq)
{
delegate_to_delegate_type_converter dtdtc = new delegate_to_delegate_type_converter(to);
add_conversion(ret, new convert_types_function_node(dtdtc.convert_delegates_to_delegates, false), from, to);
}
}
}
if (dii.parameters.Count == 0)
{