This commit is contained in:
Ivan Bondarev 2023-08-15 14:18:10 +02:00
parent 4e8c5ec89e
commit 5664851b72
3 changed files with 50 additions and 2 deletions

13
TestSuite/delegates20.pas Normal file
View file

@ -0,0 +1,13 @@
type
d1<T> = Action<procedure(a: T)>;
procedure p0(d: d1<byte>) := exit;
var i: integer;
begin
var d: d1<string>;
//Ошибка: Нельзя преобразовать тип string к byte
d := p->p('abc');
d((x: string)->begin assert(x = 'abc'); i := 1 end);
assert(i = 1);
end.

View file

@ -1266,6 +1266,37 @@ namespace PascalABCCompiler.TreeConverter
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string("System.IntPtr", sem_type.location), sem_type.location); return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string("System.IntPtr", sem_type.location), sem_type.location);
else if (sem_type is compiled_type_node ctn2 && ctn2.compiled_type == typeof(System.UIntPtr)) else if (sem_type is compiled_type_node ctn2 && ctn2.compiled_type == typeof(System.UIntPtr))
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string("System.UIntPtr", sem_type.location), sem_type.location); return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string("System.UIntPtr", sem_type.location), sem_type.location);
else if (sem_type is common_type_node && (sem_type as common_type_node).IsDelegate)
{
var tn = sem_type as common_type_node;
var invokeMeth = tn.find_first_in_type("Invoke");
if (invokeMeth != null)
{
var fn = invokeMeth.sym_info as function_node;
PascalABCCompiler.SyntaxTree.procedure_header header;
if (fn.return_value_type != null)
{
header = new PascalABCCompiler.SyntaxTree.function_header(ConvertToSyntaxType(fn.return_value_type));
}
else
{
header = new PascalABCCompiler.SyntaxTree.procedure_header();
}
header.parameters = new PascalABCCompiler.SyntaxTree.formal_parameters();
foreach (var param in fn.parameters)
{
var tparam = new PascalABCCompiler.SyntaxTree.typed_parameters();
tparam.vars_type = ConvertToSyntaxType(param.type);
tparam.idents = new PascalABCCompiler.SyntaxTree.ident_list();
tparam.idents.Add(new PascalABCCompiler.SyntaxTree.ident(param.name));
header.parameters.Add(tparam);
}
return header;
}
else
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName, sem_type.location), sem_type.location);
}
else else
return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName, sem_type.location), sem_type.location); return new PascalABCCompiler.SyntaxTree.named_type_reference(get_idents_from_dot_string(sem_type.PrintableName, sem_type.location), sem_type.location);
} }

View file

@ -18764,7 +18764,7 @@ namespace PascalABCCompiler.TreeConverter
foreach (SyntaxTree.type_definition id in types) foreach (SyntaxTree.type_definition id in types)
{ {
type_node tn = null; type_node tn = null;
if ((id is function_header || id is procedure_header) && delegate_cache.ContainsKey(id)) if ((id is function_header || id is procedure_header) && delegate_cache.ContainsKey(id) && !type_synonym_instancing)
tn = delegate_cache[id]; tn = delegate_cache[id];
else else
tn = convert_strong(id); tn = convert_strong(id);
@ -18773,7 +18773,7 @@ namespace PascalABCCompiler.TreeConverter
{ {
AddError(get_location(id), "TYPE_NAME_EXPECTED"); AddError(get_location(id), "TYPE_NAME_EXPECTED");
} }
if ((id is function_header || id is procedure_header) && !delegate_cache.ContainsKey(id)) if ((id is function_header || id is procedure_header) && !delegate_cache.ContainsKey(id) && !type_synonym_instancing)
{ {
delegate_cache[id] = tn; delegate_cache[id] = tn;
} }
@ -18934,6 +18934,8 @@ namespace PascalABCCompiler.TreeConverter
return t; return t;
} }
bool type_synonym_instancing = false;
public common_type_node instance(template_class tc, List<type_node> template_params, location loc, template_type_reference used_ttr = null) public common_type_node instance(template_class tc, List<type_node> template_params, location loc, template_type_reference used_ttr = null)
{ {
//Проверяем, что попытка инстанцирования корректна //Проверяем, что попытка инстанцирования корректна
@ -19093,7 +19095,9 @@ namespace PascalABCCompiler.TreeConverter
prm.source_context = loc; prm.source_context = loc;
} }
} }
type_synonym_instancing = true;
type_node synonym_value = convert_strong(tc.type_dec.type_def); type_node synonym_value = convert_strong(tc.type_dec.type_def);
type_synonym_instancing = false;
foreach (type_definition td in saved_sc_dict.Keys) foreach (type_definition td in saved_sc_dict.Keys)
td.source_context = saved_sc_dict[td]; td.source_context = saved_sc_dict[td];
ctn.fields.AddElement(new class_field(compiler_string_consts.synonym_value_name, ctn.fields.AddElement(new class_field(compiler_string_consts.synonym_value_name,