This commit is contained in:
Mikhalkovich Stanislav 2020-06-13 15:35:47 +03:00
parent 41316f86d1
commit ac3cb68835
10 changed files with 69 additions and 32 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "6";
public const string Build = "3";
public const string Revision = "2500";
public const string Revision = "2505";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%COREVERSION%=3
%REVISION%=2500
%MINOR%=6
%REVISION%=2505
%COREVERSION%=3
%MAJOR%=3

View file

@ -1 +1 @@
3.6.3.2500
3.6.3.2505

View file

@ -1 +1 @@
!define VERSION '3.6.3.2500'
!define VERSION '3.6.3.2505'

21
TestSuite/2067.pas Normal file
View file

@ -0,0 +1,21 @@
// #2067
type
t1<T> = class
procedure p1<T2>(f: Func<T,T2>); begin end;
end;
procedure p1<T>;
begin
var o: t1<byte>;
o.p1(b->''); // ok
end;
procedure p2<TSource>;
begin
var o: t1<TSource>;
o.p1((b: TSource): string ->'');
end;
begin
Assert(1=1)
end.

View file

@ -113,7 +113,7 @@ namespace PascalABCCompiler.TreeConverter
{
// Выводим дженерики по self
var nils = new List<int>();
var deduceSucceded = generic_convertions.DeduceInstanceTypes(selfParameter.type, patternInstance.type, deducedGenerics, nils);
var deduceSucceded = generic_convertions.DeduceInstanceTypes(selfParameter.type, patternInstance.type, deducedGenerics, nils, candidate.get_generic_params_list());
if (!deduceSucceded || deducedGenerics.Contains(null))
return false;
}

View file

@ -12,6 +12,7 @@ namespace PascalABCCompiler.TreeRealization
[Serializable]
public class expressions_list : extended_collection<expression_node>
{
public override string ToString() => string.Join(", ", this._elements);
}
[Serializable]

View file

@ -350,6 +350,7 @@ namespace PascalABCCompiler.TreeRealization
return semantic_node_type.typed_expression;
}
}
public override string ToString() => type.ToString();
}
/// <summary>

View file

@ -661,7 +661,7 @@ namespace PascalABCCompiler.TreeRealization
public static bool TryToDeduceTypesInLambda(function_lambda_definition lambda_syntax_node,
delegate_internal_interface formal_delegate,
type_node[] deduced, List<int> nils,
out Exception exception_on_body_compilation)
out Exception exception_on_body_compilation, List<type_node> generic_params)
{
var there_are_undeduced_params = false;
var param_counter = 0;
@ -744,7 +744,7 @@ namespace PascalABCCompiler.TreeRealization
}
else if (!DeduceInstanceTypes(formal_delegate.return_value_type,
(type_node)((lambda_inferred_type)lambda_syntax_node.return_type).real_type,
deduced, nils)) //Выводим дженерик-параметры после того как вычислили тип возвращаемого значения
deduced, nils, generic_params)) //Выводим дженерик-параметры после того как вычислили тип возвращаемого значения
{
result = false;
}
@ -761,6 +761,7 @@ namespace PascalABCCompiler.TreeRealization
int formal_count = formal.Count;
int fact_count = fact.Count;
int generic_type_params_count = func.generic_parameters_count;
List<type_node> generic_params = func.get_generic_params_list();
type_node[] deduced = new type_node[generic_type_params_count];
List<int> nils = new List<int>();
int count_params_to_see = fact_count;
@ -811,11 +812,11 @@ namespace PascalABCCompiler.TreeRealization
for (int i = formal_count - 1; i < fact_count; ++i)
{
//Проверяем фактические, попадающие под params...
if (!DeduceInstanceTypes(last_params_type, fact[i].type, deduced, nils))
if (!DeduceInstanceTypes(last_params_type, fact[i].type, deduced, nils, generic_params))
{
if (alone && fact[i].type is delegated_methods && (fact[i].type as delegated_methods).empty_param_method != null)
{
if (DeduceInstanceTypes(last_params_type, (fact[i].type as delegated_methods).empty_param_method.type, deduced, nils))
if (DeduceInstanceTypes(last_params_type, (fact[i].type as delegated_methods).empty_param_method.type, deduced, nils, generic_params))
continue;
}
else if (alone)
@ -840,7 +841,7 @@ namespace PascalABCCompiler.TreeRealization
type_node tn = fact[i].type;
if (tn.element_type != null && tn.type_special_kind != SemanticTree.type_special_kind.array_wrapper)
tn = tn.element_type;
if (!DeduceInstanceTypes(last_params_type, tn, deduced, nils))
if (!DeduceInstanceTypes(last_params_type, tn, deduced, nils, generic_params))
{
if (alone)
throw new SimpleSemanticError(loc, "GENERIC_FUNCTION_{0}_CAN_NOT_BE_CALLED_WITH_THESE_PARAMETERS", func.name);
@ -869,14 +870,14 @@ namespace PascalABCCompiler.TreeRealization
for (int i = 0; i < count_params_to_see; ++i)
{
if (alone && fact[i].type is delegated_methods && (fact[i].type as delegated_methods).empty_param_method != null && DeduceInstanceTypes(formal[i].type, (fact[i].type as delegated_methods).empty_param_method.type, deduced, nils))
if (alone && fact[i].type is delegated_methods && (fact[i].type as delegated_methods).empty_param_method != null && DeduceInstanceTypes(formal[i].type, (fact[i].type as delegated_methods).empty_param_method.type, deduced, nils, generic_params))
continue;
else
if (!DeduceInstanceTypes(formal[i].type, fact[i].type, deduced, nils))
if (!DeduceInstanceTypes(formal[i].type, fact[i].type, deduced, nils, generic_params))
{
if (alone && fact[i].type is delegated_methods && (fact[i].type as delegated_methods).empty_param_method != null)
{
if (DeduceInstanceTypes(formal[i].type, (fact[i].type as delegated_methods).empty_param_method.type, deduced, nils))
if (DeduceInstanceTypes(formal[i].type, (fact[i].type as delegated_methods).empty_param_method.type, deduced, nils, generic_params))
continue;
}
if (alone)
@ -916,7 +917,7 @@ namespace PascalABCCompiler.TreeRealization
Exception on_lambda_body_compile_exception;
// Исключение которое может возникнуть в результате компиляции тела лямбды если мы выберем неправильные типы параметров
var b = TryToDeduceTypesInLambda(lambda_syntax_node, formal_delegate.Value, deduced, nils,
out on_lambda_body_compile_exception);
out on_lambda_body_compile_exception, generic_params);
if (!b)
// Пробуем вычислить типы из лямбд
{
@ -961,12 +962,12 @@ namespace PascalABCCompiler.TreeRealization
type_node[] tmp_deduced = (type_node[])deduced.Clone();
List<int> tmp_nils = new List<int>();
tmp_nils.AddRange(nils);
if (!DeduceInstanceTypes(formal[count_params_to_see].type, fact[count_params_to_see].type, deduced, nils))
if (!DeduceInstanceTypes(formal[count_params_to_see].type, fact[count_params_to_see].type, deduced, nils, generic_params))
{
//Второй шанс. Учитываем слово params.
deduced = tmp_deduced;
nils = tmp_nils;
if (!DeduceInstanceTypes(formal[count_params_to_see].type.element_type, fact[count_params_to_see].type, deduced, nils))
if (!DeduceInstanceTypes(formal[count_params_to_see].type.element_type, fact[count_params_to_see].type, deduced, nils, generic_params))
{
if (alone)
throw new SimpleSemanticError(loc, "GENERIC_FUNCTION_{0}_CAN_NOT_BE_CALLED_WITH_THESE_PARAMETERS", func.name);
@ -1010,7 +1011,12 @@ namespace PascalABCCompiler.TreeRealization
}
//Выведение типов
public static bool DeduceInstanceTypes(type_node formal_type, type_node fact_type, type_node[] deduced, List<int> nils)
//Странно, что для вывода ОДНОГО параметра передаётся весь массив deduced!!!
//Непонятно, что делать, если мы сюда заходим, а он уже в том месте заполнен. Это ошибка или нет?
//Может ли быть такое, что deduced[par_num] заполнен, а возвращается false?
//Не может ли быть, что при рекурсивном вызове deduced начинает перезаполняться вовсе для других параметров?
//Где потом используется deduced?
public static bool DeduceInstanceTypes(type_node formal_type, type_node fact_type, type_node[] deduced, List<int> nils, List<type_node> generic_params)
{
if (fact_type == null)//issue #347
return false;
@ -1024,6 +1030,11 @@ namespace PascalABCCompiler.TreeRealization
//Формальный тип - generic-параметр функции. Выводим.
if (formal_type.generic_function_container != null)
{
// SSM 13/06/20 Если formal_type не входит в generic_params, то вернуть false
if (!generic_params.Contains(formal_type)) // SSM 13.06.20 #2067
{
return true; // т.е. вывод закончен - нечего выводить
}
int par_num = formal_type.generic_param_index;
if (fact_type.semantic_node_type == semantic_node_type.null_type_node)
{
@ -1065,7 +1076,7 @@ namespace PascalABCCompiler.TreeRealization
{
goto eq_cmp;
}
return DeduceInstanceTypes(formal_ref.pointed_type, fact_ref.pointed_type, deduced, nils);
return DeduceInstanceTypes(formal_ref.pointed_type, fact_ref.pointed_type, deduced, nils, generic_params);
}
//безразмерные массивы
array_internal_interface formal_ii = formal_type.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface;
@ -1076,25 +1087,25 @@ namespace PascalABCCompiler.TreeRealization
{
goto eq_cmp;
}
return DeduceInstanceTypes(formal_ii.element_type, fact_ii.element_type, deduced, nils);
return DeduceInstanceTypes(formal_ii.element_type, fact_ii.element_type, deduced, nils, generic_params);
}
//множества
//Множества
if (formal_type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.set_type)
{
if (fact_type.type_special_kind != PascalABCCompiler.SemanticTree.type_special_kind.set_type)
{
goto eq_cmp;
}
return DeduceInstanceTypes(formal_type.element_type, fact_type.element_type, deduced, nils);
return DeduceInstanceTypes(formal_type.element_type, fact_type.element_type, deduced, nils, generic_params);
}
//множества
//Типизированные файлы
if (formal_type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.typed_file)
{
if (fact_type.type_special_kind != PascalABCCompiler.SemanticTree.type_special_kind.typed_file)
{
goto eq_cmp;
}
return DeduceInstanceTypes(formal_type.element_type, fact_type.element_type, deduced, nils);
return DeduceInstanceTypes(formal_type.element_type, fact_type.element_type, deduced, nils, generic_params);
}
//Делегаты
if (formal_type.IsDelegate)
@ -1128,7 +1139,7 @@ namespace PascalABCCompiler.TreeRealization
continue;
}
// 07.04.15 - SSM поменял местами первые 2 параметра - видимо, была ошибка
if (!DeduceInstanceTypes(dii.parameters[i].type, fact_func.parameters[i].type, deduced, nils))
if (!DeduceInstanceTypes(dii.parameters[i].type, fact_func.parameters[i].type, deduced, nils, generic_params))
//if (!DeduceInstanceTypes(fact_func.parameters[i].type, dii.parameters[i].type, deduced, nils))
{
goto eq_cmp;
@ -1147,7 +1158,7 @@ namespace PascalABCCompiler.TreeRealization
return true;
}
// 07.04.15 - SSM поменял местами первые 2 параметра - видимо, была ошибка
else if (fact_func.return_value_type == null || !DeduceInstanceTypes(dii.return_value_type, fact_func.return_value_type, deduced, nils)) // SSM 29.05.14 - не выводится если IEnumerable<TResult>
else if (fact_func.return_value_type == null || !DeduceInstanceTypes(dii.return_value_type, fact_func.return_value_type, deduced, nils, generic_params)) // SSM 29.05.14 - не выводится если IEnumerable<TResult>
// else if (fact_func.return_value_type == null || !DeduceInstanceTypes(fact_func.return_value_type, dii.return_value_type, deduced, nils)) // SSM 29.05.14 - не выводится если IEnumerable<TResult>
{
goto eq_cmp;
@ -1184,7 +1195,7 @@ namespace PascalABCCompiler.TreeRealization
}
for (int i = 0; i < param_count; i++)
{
if (!DeduceInstanceTypes(dii.parameters[i].type, fact_func.parameters[i].type, deduced, nils)) // 07.04.15 - SSM поменял местами первые 2 параметра - видимо, была ошибка
if (!DeduceInstanceTypes(dii.parameters[i].type, fact_func.parameters[i].type, deduced, nils, generic_params)) // 07.04.15 - SSM поменял местами первые 2 параметра - видимо, была ошибка
//if (!DeduceInstanceTypes(fact_func.parameters[i].type, dii.parameters[i].type, deduced, nils))
{
goto eq_cmp;
@ -1199,7 +1210,7 @@ namespace PascalABCCompiler.TreeRealization
goto eq_cmp;
}
// 07.04.15 - SSM поменял местами первые 2 параметра - видимо, была ошибка
else if (fact_func.return_value_type == null || !DeduceInstanceTypes(dii.return_value_type, fact_func.return_value_type, deduced, nils)) // SSM 29.05.14 - не выводится если IEnumerable<TResult>
else if (fact_func.return_value_type == null || !DeduceInstanceTypes(dii.return_value_type, fact_func.return_value_type, deduced, nils, generic_params)) // SSM 29.05.14 - не выводится если IEnumerable<TResult>
// else if (fact_func.return_value_type == null || !DeduceInstanceTypes(fact_func.return_value_type, dii.return_value_type, deduced, nils)) // SSM 29.05.14 - не выводится если IEnumerable<TResult>
{
goto eq_cmp;
@ -1248,7 +1259,7 @@ namespace PascalABCCompiler.TreeRealization
int pcount = formal_type.instance_params.Count;
for (int k = 0; k < pcount; ++k)
{
if (!DeduceInstanceTypes(formal_type.instance_params[k], fact_type_converted.instance_params[k], deduced, nils))
if (!DeduceInstanceTypes(formal_type.instance_params[k], fact_type_converted.instance_params[k], deduced, nils, generic_params))
{
goto eq_cmp;
}

View file

@ -675,6 +675,7 @@ namespace PascalABCCompiler.TreeRealization
}
}
public override string ToString() => "λ_anytype";
}
[Serializable]
@ -4663,15 +4664,15 @@ namespace PascalABCCompiler.TreeRealization
case SemanticTree.parameter_type.var : sb.Append("var "); break;
}
if (prm.is_params) sb.Append("params ");
sb.Append(prm.name+": ");
sb.Append(prm.type.name);
sb.Append((prm.name ?? "_") +": ");
sb.Append(prm.type.ToString());
if (i<bfc.function.parameters.Length-1)
sb.Append(';');
}
sb.Append(')');
}
if (bfc.function.return_value_type != null)
sb.Append(": "+bfc.function.return_value_type.name);
sb.Append(": "+bfc.function.return_value_type.ToString());
return sb.ToString();
}
@ -4685,6 +4686,8 @@ namespace PascalABCCompiler.TreeRealization
}
}
public override string ToString() => name;
public override List<SymbolInfo> find(string name, bool no_search_in_extension_methods = false)
{
return find_in_type(name);