diff --git a/TestSuite/lambda_where_1.pas b/TestSuite/lambda_where_1.pas new file mode 100644 index 000000000..dad59f0cd --- /dev/null +++ b/TestSuite/lambda_where_1.pas @@ -0,0 +1,14 @@ +type + r1 = record + where T: record; + end; + +//Ошибка: Невозможно инстанцировать, так как тип T не является размерным +procedure p1; where T: record; +begin + // Обязательно лямбда + // Обязательно возвращаемое значение, но неважно какое + var f: r1->byte := r->0; +end; + +begin end. \ No newline at end of file diff --git a/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutor.cs b/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutor.cs index 4368f8192..426e0724f 100644 --- a/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutor.cs +++ b/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutor.cs @@ -1056,19 +1056,22 @@ namespace TreeConverter.LambdaExpressions.Closure types = new where_type_specificator_list() }; - if (el.base_class != null && el.base_class != SystemLibrary.object_type) + var base_describes_type = false; + if (el.base_class != SystemLibrary.object_type) { + base_describes_type = el.base_class != SystemLibrary.enum_base_type; var d = LambdaHelper.ConvertSemanticTypeToSyntaxType(el.base_class); whereDef.types.Add(d); } - else if (el.is_class) + + if (el.is_class && !base_describes_type) { var d = new declaration_specificator(DeclarationSpecificator.WhereDefClass, "class"); whereDef.types.Add(d); } - if (el.is_value) { + if (base_describes_type) throw new InvalidOperationException($"where with record and base other then enum"); var d = new declaration_specificator(DeclarationSpecificator.WhereDefValueType, "record"); whereDef.types.Add(d); } diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index fdabef8a5..b7176d45f 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -13070,10 +13070,19 @@ namespace PascalABCCompiler.TreeConverter { visit_generic_params(context.top_function, _function_header.template_args.idents); } + + if (_function_header.where_defs != null) + visit_where_list(_function_header.where_defs); + SymbolInfo si = context.create_special_names(); weak_node_test_and_visit(_function_header.parameters); type_node tn = null; + bool unique = context.close_function_params(body_exists); + if (!unique && _function_header.where_defs != null) + // Видимо, ошибка только для глобальных forward продпрограмм + AddError(get_location(_function_header.where_defs), "WHERE_SECTION_MUST_BE_ONLY_IN_FIRST_DECLARATION"); + #region Вывод типа возвращаемого значения лямбды //lroman// @@ -13159,20 +13168,8 @@ namespace PascalABCCompiler.TreeConverter } CheckOverrideOrReintroduceExpectedWarning(get_location(_function_header)); - bool unique = context.close_function_params(body_exists); if (context.top_function.return_value_type == null) AddError(get_location(_function_header), "FUNCTION_NEED_RETURN_TYPE"); - if (_function_header.where_defs != null) - { - if (unique) - { - visit_where_list(_function_header.where_defs); - } - else - { - AddError(get_location(_function_header.where_defs), "WHERE_SECTION_MUST_BE_ONLY_IN_FIRST_DECLARATION"); - } - } convertion_data_and_alghoritms.create_function_return_variable(context.top_function, si); //TODO: Разобрать подробнее.