From 50500088794bc4f525b096062fd0847818235d04 Mon Sep 17 00:00:00 2001 From: Ivan Bondarev Date: Sun, 21 Mar 2021 13:46:54 +0100 Subject: [PATCH] fix #2457 --- TestSuite/implicitexplicit14.pas | 21 +++++++++++++++++++++ TreeConverter/NetWrappers/NetHelper.cs | 8 +++++--- TreeConverter/TreeRealization/types.cs | 15 ++++++--------- 3 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 TestSuite/implicitexplicit14.pas diff --git a/TestSuite/implicitexplicit14.pas b/TestSuite/implicitexplicit14.pas new file mode 100644 index 000000000..fea354a8d --- /dev/null +++ b/TestSuite/implicitexplicit14.pas @@ -0,0 +1,21 @@ +type + TClass = auto class + i: integer + end; + +function operator implicit(i: integer): set of integer; extensionmethod; +begin + Result := [i]; +end; + +function operator implicit(i: integer): TClass; extensionmethod; +begin + Result := new TClass(i); +end; + +begin + var s: set of integer := 2; + assert(s = [2]); + var o: TClass := 2; + assert(o.i = 2); +end. \ No newline at end of file diff --git a/TreeConverter/NetWrappers/NetHelper.cs b/TreeConverter/NetWrappers/NetHelper.cs index 93471b4e4..875d8d677 100644 --- a/TreeConverter/NetWrappers/NetHelper.cs +++ b/TreeConverter/NetWrappers/NetHelper.cs @@ -1070,7 +1070,7 @@ namespace PascalABCCompiler.NetHelper } private static function_node get_conversion(compiled_type_node in_type,compiled_type_node from, - compiled_type_node to,string op_name, NetTypeScope scope) + type_node to, string op_name, NetTypeScope scope) { //MethodInfo[] mia = in_type.compiled_type.GetMethods(); List mia = GetMembers(in_type.compiled_type, op_name); @@ -1079,8 +1079,10 @@ namespace PascalABCCompiler.NetHelper { if (!(mbi is MethodInfo)) continue; + if (!(to is compiled_type_node)) + continue; MethodInfo mi = mbi as MethodInfo; - if (mi.ReturnType != to.compiled_type) + if (mi.ReturnType != (to as compiled_type_node).compiled_type) { continue; } @@ -1118,7 +1120,7 @@ namespace PascalABCCompiler.NetHelper } public static function_node get_implicit_conversion(compiled_type_node in_type, compiled_type_node from, - compiled_type_node to, NetTypeScope scope) + type_node to, NetTypeScope scope) { return get_conversion(in_type, from, to, compiler_string_consts.implicit_operator_name, scope); } diff --git a/TreeConverter/TreeRealization/types.cs b/TreeConverter/TreeRealization/types.cs index 9a3414e11..e5b8bba4b 100644 --- a/TreeConverter/TreeRealization/types.cs +++ b/TreeConverter/TreeRealization/types.cs @@ -3683,19 +3683,16 @@ namespace PascalABCCompiler.TreeRealization { // То есть получается, что конвертировать откомпилированный тип в неоткомпилированный нельзя несмотря на то что есть extension оператор var cctn = ctn as compiled_type_node; - if (cctn == null) - { - return null; - } + function_node fn = null; - if (!_implicit_convertions_to.TryGetValue(cctn, out fn)) + if (!_implicit_convertions_to.TryGetValue(ctn, out fn)) { - fn = NetHelper.NetHelper.get_implicit_conversion(this, this, cctn, scope); + fn = NetHelper.NetHelper.get_implicit_conversion(this, this, ctn, scope); if (fn is compiled_function_node) - _implicit_convertions_to.Add(cctn, fn); + _implicit_convertions_to.Add(ctn, fn); else if (fn == null && this.type_special_kind == SemanticTree.type_special_kind.array_kind && this.base_type.Scope != null) { - fn = NetHelper.NetHelper.get_implicit_conversion(this.base_type as compiled_type_node, this.base_type as compiled_type_node, cctn, this.base_type.Scope as NetHelper.NetTypeScope); + fn = NetHelper.NetHelper.get_implicit_conversion(this.base_type as compiled_type_node, this.base_type as compiled_type_node, ctn, this.base_type.Scope as NetHelper.NetTypeScope); if (fn != null) { List instance_params = new List(); @@ -3704,7 +3701,7 @@ namespace PascalABCCompiler.TreeRealization return fn; } } - else if (fn == null && (this.is_generic_type_instance || cctn.is_generic_type_instance)) + else if (fn == null && cctn != null && (this.is_generic_type_instance || cctn.is_generic_type_instance)) { List instance_params1 = this.instance_params; List instance_params2 = cctn.instance_params;