diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index 2392f7399..d1fe6a607 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -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; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index 728927af9..05f322eb3 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ -%COREVERSION%=3 -%REVISION%=2500 %MINOR%=6 +%REVISION%=2505 +%COREVERSION%=3 %MAJOR%=3 diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index 31dd30bbc..ea14cb695 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.6.3.2500 +3.6.3.2505 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 871d4a903..033efc722 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.6.3.2500' +!define VERSION '3.6.3.2505' diff --git a/TestSuite/2067.pas b/TestSuite/2067.pas new file mode 100644 index 000000000..fedc95e51 --- /dev/null +++ b/TestSuite/2067.pas @@ -0,0 +1,21 @@ +// #2067 +type + t1 = class + procedure p1(f: Func); begin end; + end; + +procedure p1; +begin + var o: t1; + o.p1(b->''); // ok +end; + +procedure p2; +begin + var o: t1; + o.p1((b: TSource): string ->''); +end; + +begin + Assert(1=1) +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Patterns.cs b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Patterns.cs index 31218743f..39998c786 100644 --- a/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Patterns.cs +++ b/TreeConverter/TreeConversion/SyntaxTreeVisitorNodes/Patterns.cs @@ -113,7 +113,7 @@ namespace PascalABCCompiler.TreeConverter { // Выводим дженерики по self var nils = new List(); - 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; } diff --git a/TreeConverter/TreeRealization/Collections.cs b/TreeConverter/TreeRealization/Collections.cs index ca101fae7..f59ffb63f 100644 --- a/TreeConverter/TreeRealization/Collections.cs +++ b/TreeConverter/TreeRealization/Collections.cs @@ -12,6 +12,7 @@ namespace PascalABCCompiler.TreeRealization [Serializable] public class expressions_list : extended_collection { + public override string ToString() => string.Join(", ", this._elements); } [Serializable] diff --git a/TreeConverter/TreeRealization/base_nodes.cs b/TreeConverter/TreeRealization/base_nodes.cs index 1e33b2ba8..f0b61822f 100644 --- a/TreeConverter/TreeRealization/base_nodes.cs +++ b/TreeConverter/TreeRealization/base_nodes.cs @@ -350,6 +350,7 @@ namespace PascalABCCompiler.TreeRealization return semantic_node_type.typed_expression; } } + public override string ToString() => type.ToString(); } /// diff --git a/TreeConverter/TreeRealization/generics.cs b/TreeConverter/TreeRealization/generics.cs index 99a1f1c13..d31651aa1 100644 --- a/TreeConverter/TreeRealization/generics.cs +++ b/TreeConverter/TreeRealization/generics.cs @@ -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 nils, - out Exception exception_on_body_compilation) + out Exception exception_on_body_compilation, List 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 generic_params = func.get_generic_params_list(); type_node[] deduced = new type_node[generic_type_params_count]; List nils = new List(); 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 tmp_nils = new List(); 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 nils) + //Странно, что для вывода ОДНОГО параметра передаётся весь массив deduced!!! + //Непонятно, что делать, если мы сюда заходим, а он уже в том месте заполнен. Это ошибка или нет? + //Может ли быть такое, что deduced[par_num] заполнен, а возвращается false? + //Не может ли быть, что при рекурсивном вызове deduced начинает перезаполняться вовсе для других параметров? + //Где потом используется deduced? + public static bool DeduceInstanceTypes(type_node formal_type, type_node fact_type, type_node[] deduced, List nils, List 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 + 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 // 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 { 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 + 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 // 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 { 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; } diff --git a/TreeConverter/TreeRealization/types.cs b/TreeConverter/TreeRealization/types.cs index 18aa7267e..3ca7c1686 100644 --- a/TreeConverter/TreeRealization/types.cs +++ b/TreeConverter/TreeRealization/types.cs @@ -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 name; + public override List find(string name, bool no_search_in_extension_methods = false) { return find_in_type(name);