From 60754de5f37303a3905bfad5e577787fd3118d6d Mon Sep 17 00:00:00 2001 From: Ivan Bondarev Date: Wed, 29 Dec 2021 12:24:38 +0100 Subject: [PATCH] #2594 --- NETGenerator/NETGenerator.cs | 29 +++++++++++++++++++++++++++-- TestSuite/genericrecords3.pas | 13 +++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 TestSuite/genericrecords3.pas diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index a463c887c..02d85b810 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -1272,6 +1272,7 @@ namespace PascalABCCompiler.NETGenerator private void CloseTypes() { //(ssyy) TODO: подумать, в каком порядке создавать типы + List closed_types = new List(); for (int i = 0; i < types.Count; i++) if (types[i].IsInterface) try @@ -1298,10 +1299,34 @@ namespace PascalABCCompiler.NETGenerator } catch (TypeLoadException ex) { - SemanticTree.ICommonTypeNode ctn = helper.GetTypeNodeByTypeBuilder(value_types[i]); if (ctn != null) { + if (ctn.is_generic_type_definition) + { + bool has_class_contrains = false; + foreach (var gp in ctn.generic_params) + { + if (!(gp.base_type is ICommonTypeNode)) + continue; + TypeBuilder tb = helper.GetTypeReference(gp.base_type).tp as TypeBuilder; + if (tb != null) + { + try + { + tb.CreateType(); + closed_types.Add(tb); + has_class_contrains = true; + } + catch (TypeLoadException ex2) + { + + } + } + } + if (has_class_contrains) + continue; + } IAttributeNode[] attrs = ctn.Attributes; if (attrs.Length > 0 && attrs[0].AttributeType is ICompiledTypeNode && (attrs[0].AttributeType as ICompiledTypeNode).compiled_type == typeof(System.Runtime.InteropServices.StructLayoutAttribute)) { @@ -1317,7 +1342,7 @@ namespace PascalABCCompiler.NETGenerator } List failed_types = new List(); for (int i = 0; i < types.Count; i++) - if (!types[i].IsInterface) + if (!types[i].IsInterface && !closed_types.Contains(types[i])) { try { diff --git a/TestSuite/genericrecords3.pas b/TestSuite/genericrecords3.pas new file mode 100644 index 000000000..e9fe011e4 --- /dev/null +++ b/TestSuite/genericrecords3.pas @@ -0,0 +1,13 @@ +type + t1 = class end; + + t2 = record + where T: t1; + a: T; + end; + +begin + var r: t2; + r.a := new t1; + assert(r.a <> nil); +end. \ No newline at end of file