This commit is contained in:
Ivan Bondarev 2021-03-21 13:46:54 +01:00
parent 072c2ac487
commit 5050008879
3 changed files with 32 additions and 12 deletions

View file

@ -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.

View file

@ -1070,7 +1070,7 @@ namespace PascalABCCompiler.NetHelper
} }
private static function_node get_conversion(compiled_type_node in_type,compiled_type_node from, 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(); //MethodInfo[] mia = in_type.compiled_type.GetMethods();
List<MemberInfo> mia = GetMembers(in_type.compiled_type, op_name); List<MemberInfo> mia = GetMembers(in_type.compiled_type, op_name);
@ -1079,8 +1079,10 @@ namespace PascalABCCompiler.NetHelper
{ {
if (!(mbi is MethodInfo)) if (!(mbi is MethodInfo))
continue; continue;
if (!(to is compiled_type_node))
continue;
MethodInfo mi = mbi as MethodInfo; MethodInfo mi = mbi as MethodInfo;
if (mi.ReturnType != to.compiled_type) if (mi.ReturnType != (to as compiled_type_node).compiled_type)
{ {
continue; continue;
} }
@ -1118,7 +1120,7 @@ namespace PascalABCCompiler.NetHelper
} }
public static function_node get_implicit_conversion(compiled_type_node in_type, compiled_type_node from, 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); return get_conversion(in_type, from, to, compiler_string_consts.implicit_operator_name, scope);
} }

View file

@ -3683,19 +3683,16 @@ namespace PascalABCCompiler.TreeRealization
{ {
// То есть получается, что конвертировать откомпилированный тип в неоткомпилированный нельзя несмотря на то что есть extension оператор // То есть получается, что конвертировать откомпилированный тип в неоткомпилированный нельзя несмотря на то что есть extension оператор
var cctn = ctn as compiled_type_node; var cctn = ctn as compiled_type_node;
if (cctn == null)
{
return null;
}
function_node fn = 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) 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) 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) if (fn != null)
{ {
List<type_node> instance_params = new List<type_node>(); List<type_node> instance_params = new List<type_node>();
@ -3704,7 +3701,7 @@ namespace PascalABCCompiler.TreeRealization
return fn; 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<type_node> instance_params1 = this.instance_params; List<type_node> instance_params1 = this.instance_params;
List<type_node> instance_params2 = cctn.instance_params; List<type_node> instance_params2 = cctn.instance_params;