diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index d419091b2..4fd0ed606 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -5275,6 +5275,11 @@ namespace PascalABCCompiler.NETGenerator if (!(value.type.is_generic_parameter && value.type.base_type != null && value.type.base_type.is_class && value.type.base_type.base_type != null)) must_push_addr = true; } + else if (value.conversion_type != null && (value.conversion_type.is_generic_parameter)) + { + if (!(value.conversion_type.is_generic_parameter && value.conversion_type.base_type != null && value.conversion_type.base_type.is_class && value.conversion_type.base_type.base_type != null)) + must_push_addr = true; + } } ParamInfo pi = helper.GetParameter(value.parameter); if (pi.kind == ParamKind.pkNone) @@ -7090,6 +7095,8 @@ namespace PascalABCCompiler.NETGenerator { if (value.obj.type.is_generic_parameter) il.Emit(OpCodes.Constrained, helper.GetTypeReference(value.obj.type).tp); + else if (value.obj.conversion_type != null && value.obj.conversion_type.is_generic_parameter) + il.Emit(OpCodes.Constrained, helper.GetTypeReference(value.obj.conversion_type).tp); il.EmitCall(OpCodes.Callvirt, mi, null); } @@ -7219,6 +7226,8 @@ namespace PascalABCCompiler.NETGenerator { if (value.obj.type.is_generic_parameter) il.Emit(OpCodes.Constrained, helper.GetTypeReference(value.obj.type).tp); + else if (value.obj.conversion_type != null && value.obj.conversion_type.is_generic_parameter) + il.Emit(OpCodes.Constrained, helper.GetTypeReference(value.obj.conversion_type).tp); il.EmitCall(OpCodes.Callvirt, mi, null); } EmitFreePinnedVariables(); diff --git a/TestSuite/generics35.pas b/TestSuite/generics35.pas new file mode 100644 index 000000000..a7b5ea5b4 --- /dev/null +++ b/TestSuite/generics35.pas @@ -0,0 +1,22 @@ +var i: integer; +type + I1 = interface + procedure p1; + end; + + r1 = record(I1) + public procedure p1; + begin + i := 1; + end; + end; + +procedure p1(a: T); where T: I1; +begin + I1(a).p1; +end; + +begin + p1(new r1); + assert(i = 1); +end. \ No newline at end of file diff --git a/TestSuite/generics36.pas b/TestSuite/generics36.pas new file mode 100644 index 000000000..9cb262def --- /dev/null +++ b/TestSuite/generics36.pas @@ -0,0 +1,18 @@ +var i: integer; +type + r1 = record(System.ICloneable) + public function Clone: object; + begin + i := 1; + end; + end; + +procedure p1(a: T); where T: System.ICloneable; +begin + System.ICloneable(a).Clone; +end; + +begin + p1(new r1); + assert(i = 1); +end. \ No newline at end of file