diff --git a/TestSuite/lambdas_generics13.pas b/TestSuite/lambdas_generics13.pas new file mode 100644 index 000000000..b36fc4899 --- /dev/null +++ b/TestSuite/lambdas_generics13.pas @@ -0,0 +1,14 @@ +type + t0 = class + end; + +procedure p1; +where T: t0; +begin + var o: T; + var p := procedure -> o := o; +end; + +begin + p1&; +end. \ No newline at end of file diff --git a/TestSuite/lambdas_generics14.pas b/TestSuite/lambdas_generics14.pas new file mode 100644 index 000000000..ca08b558a --- /dev/null +++ b/TestSuite/lambdas_generics14.pas @@ -0,0 +1,15 @@ +type + t0 = class + //constructor := exit; + end; + +procedure p1; +where T: t0, constructor; +begin + var o: T; + var p := procedure -> o := o; +end; + +begin + p1&; +end. \ No newline at end of file diff --git a/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutor.cs b/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutor.cs index e3f56ba72..a1e3953d9 100644 --- a/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutor.cs +++ b/TreeConverter/LambdaExpressions/Closure/CapturedVariablesSubstitutor.cs @@ -1079,7 +1079,7 @@ namespace TreeConverter.LambdaExpressions.Closure whereDef.types.Add(d); } - if (el.has_default_ctor) + if (el.has_explicit_default_ctor) { var d = new declaration_specificator(DeclarationSpecificator.WhereDefConstructor, "constructor"); whereDef.types.Add(d); @@ -1116,7 +1116,11 @@ namespace TreeConverter.LambdaExpressions.Closure List lst = generic_parameter_eliminations.make_eliminations_common(_visitor.context._ctn.generic_params); for (int i = 0; i < lst.Count; i++) if (!lst[i].has_default_ctor && _visitor.context._ctn.generic_params[i] is common_type_node) + { lst[i].has_default_ctor = (_visitor.context._ctn.generic_params[i] as common_type_node).has_default_constructor; + lst[i].has_explicit_default_ctor = (_visitor.context._ctn.generic_params[i] as common_type_node).has_explicit_default_constructor; + } + genericParameterEliminations.AddRange(lst); } diff --git a/TreeConverter/TreeRealization/generics.cs b/TreeConverter/TreeRealization/generics.cs index 921d20f82..001116943 100644 --- a/TreeConverter/TreeRealization/generics.cs +++ b/TreeConverter/TreeRealization/generics.cs @@ -43,6 +43,7 @@ namespace PascalABCCompiler.TreeRealization public bool is_class = false; public bool is_value = false; public bool has_default_ctor = false; + public bool has_explicit_default_ctor = false; public type_node base_class = null; public List implementing_interfaces = null; @@ -56,6 +57,7 @@ namespace PascalABCCompiler.TreeRealization param.methods.AddElement(cnode); param.add_name(compiler_string_consts.default_constructor_name, new SymbolInfo(cnode)); param.has_default_constructor = true; + param.has_explicit_default_constructor = true; } public static List make_eliminations_common(List generic_params) @@ -65,6 +67,8 @@ namespace PascalABCCompiler.TreeRealization { generic_parameter_eliminations gpe = new generic_parameter_eliminations(); gpe.has_default_ctor = generic_convertions.type_has_default_ctor(t, false); + if (t is common_type_node && (t as common_type_node).has_explicit_default_constructor) + gpe.has_explicit_default_ctor = true; gpe.is_class = t.is_class; gpe.is_value = t.is_value; gpe.base_class = t.base_type; @@ -87,6 +91,8 @@ namespace PascalABCCompiler.TreeRealization gpe.has_default_ctor = ((t.GenericParameterAttributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0); + if (gpe.has_default_ctor) + gpe.has_explicit_default_ctor = true; gpe.is_class = ((t.GenericParameterAttributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0); diff --git a/TreeConverter/TreeRealization/types.cs b/TreeConverter/TreeRealization/types.cs index 7a3b038c5..9a3414e11 100644 --- a/TreeConverter/TreeRealization/types.cs +++ b/TreeConverter/TreeRealization/types.cs @@ -1270,6 +1270,7 @@ namespace PascalABCCompiler.TreeRealization private SymbolTable.ClassScope _scope; public bool has_default_constructor = false; + public bool has_explicit_default_constructor = false; public bool has_user_defined_constructor = false; private bool _has_static_constructor = false;