diff --git a/Compiler/PCU/PCUReader.cs b/Compiler/PCU/PCUReader.cs index 02dbdc62e..fcca851b7 100644 --- a/Compiler/PCU/PCUReader.cs +++ b/Compiler/PCU/PCUReader.cs @@ -2211,6 +2211,10 @@ namespace PascalABCCompiler.PCU ctn.type_special_kind = tsk; if (ctn.full_name == "PABCSystem.BinaryFile") ctn.type_special_kind = SemanticTree.type_special_kind.binary_file; + if (ctn.type_special_kind != SemanticTree.type_special_kind.set_type) + { + SystemLibrary.SystemLibrary.init_reference_type(ctn); + } if (type_is_generic_definition) { foreach (common_type_node par in type_params) @@ -2219,14 +2223,11 @@ namespace PascalABCCompiler.PCU ReadTypeParameterEliminations(par); } } - type_node elemnet_type = null; + type_node element_type = null; if (CanReadObject()) - elemnet_type = GetTypeReference(); - ctn.element_type = elemnet_type; - if (ctn.type_special_kind != SemanticTree.type_special_kind.set_type) - { - SystemLibrary.SystemLibrary.init_reference_type(ctn); - } + element_type = GetTypeReference(); + ctn.element_type = element_type; + if (ctn.type_special_kind == SemanticTree.type_special_kind.set_type) { ctn = compilation_context.AddTypeToSetTypeList(ctn); diff --git a/TestSuite/errors/err0393.pas b/TestSuite/errors/err0393.pas new file mode 100644 index 000000000..6bab2156b --- /dev/null +++ b/TestSuite/errors/err0393.pas @@ -0,0 +1,12 @@ +type + t0 = class end; + + t1 = class + where T: t0; + + end; + +begin + // Компилируется, а не должно + var a: t1; +end. \ No newline at end of file diff --git a/TestSuite/units/u_where2.pas b/TestSuite/units/u_where2.pas new file mode 100644 index 000000000..2f108cde0 --- /dev/null +++ b/TestSuite/units/u_where2.pas @@ -0,0 +1,12 @@ +unit u_where2; + +type + + t0 = class + where T: t0; + + procedure p1(a: T); virtual := exit; + + end; + +end. \ No newline at end of file diff --git a/TestSuite/usesunits/use_where2.pas b/TestSuite/usesunits/use_where2.pas new file mode 100644 index 000000000..58912ddf1 --- /dev/null +++ b/TestSuite/usesunits/use_where2.pas @@ -0,0 +1,19 @@ +uses u_where2; + +var i: integer; +type + + t1 = class(t0) + + procedure p1(a: t1); override; + begin + i := 1; + end; + + end; + +begin +var obj := new t1; +obj.p1(obj); +assert(i = 1); +end. \ No newline at end of file diff --git a/TreeConverter/TreeRealization/generics.cs b/TreeConverter/TreeRealization/generics.cs index 7811a950f..8996ff0ec 100644 --- a/TreeConverter/TreeRealization/generics.cs +++ b/TreeConverter/TreeRealization/generics.cs @@ -166,6 +166,10 @@ namespace PascalABCCompiler.TreeRealization return new SimpleSemanticError(null, "PARAMETER_{0}_MUST_BE_DERIVED_FROM_{1}", tn.PrintableName, base_type.name); } } + if (gpe.base_class != null && gpe.base_class != SystemLibrary.SystemLibrary.object_type && tn.is_value && !gpe.base_class.is_value && gpe.base_class != SystemLibrary.SystemLibrary.value_type) + { + return new SimpleSemanticError(null, "PARAMETER_{0}_MUST_BE_REFERENCE_TYPE", tn.PrintableName); + } foreach (type_node interf in gpe.implementing_interfaces) { type_node di = generic_convertions.determine_type(interf, tparams, method_param_types);