This commit is contained in:
parent
48f2ed4967
commit
62f031f0d0
18
TestSuite/errors/err0438.pas
Normal file
18
TestSuite/errors/err0438.pas
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
//!Нельзя преобразовать тип t0<t0<string>> к t1
|
||||||
|
var i: integer;
|
||||||
|
type
|
||||||
|
t0<T> = class end;
|
||||||
|
t2<T> = class end;
|
||||||
|
t1 = class
|
||||||
|
|
||||||
|
static function operator implicit<T>(a: t0<t0<T>>): t1; where T: record;
|
||||||
|
begin
|
||||||
|
i := 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
var a: t0<t0<string>>;
|
||||||
|
var k: t1 := a;
|
||||||
|
end.
|
||||||
18
TestSuite/errors/err0439.pas
Normal file
18
TestSuite/errors/err0439.pas
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
//!Нельзя преобразовать тип t0<t0<t2<byte>>> к t1
|
||||||
|
var i: integer;
|
||||||
|
type
|
||||||
|
t0<T> = class end;
|
||||||
|
t2<T> = class end;
|
||||||
|
t1 = class
|
||||||
|
|
||||||
|
static function operator implicit<T>(a: t0<t0<t0<T>>>): t1; where T: record;
|
||||||
|
begin
|
||||||
|
i := 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
var a: t0<t0<t2<byte>>>;
|
||||||
|
var k: t1 := a;
|
||||||
|
end.
|
||||||
18
TestSuite/errors/err0440.pas
Normal file
18
TestSuite/errors/err0440.pas
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
//!Нельзя преобразовать тип Generic2<byte,Generic1<string>> к ConvTarget
|
||||||
|
type
|
||||||
|
Generic1<T> = class end;
|
||||||
|
Generic2<T1,T2> = class end;
|
||||||
|
|
||||||
|
ConvTarget = class
|
||||||
|
|
||||||
|
static function operator implicit<T1, T2>(o: Generic2<T1, Generic1<T2>>): ConvTarget; where T1, T2: record;
|
||||||
|
begin
|
||||||
|
Result := new ConvTarget;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
var a: Generic2<byte, Generic1<string>>;
|
||||||
|
var o: ConvTarget := a;
|
||||||
|
end.
|
||||||
24
TestSuite/implicitexplicit19.pas
Normal file
24
TestSuite/implicitexplicit19.pas
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
var i: integer;
|
||||||
|
type
|
||||||
|
t0<T> = class end;
|
||||||
|
t2<T> = class end;
|
||||||
|
t1 = class
|
||||||
|
|
||||||
|
static function operator implicit<T>(a: t0<t0<T>>): t1; where T: record;
|
||||||
|
begin
|
||||||
|
i := 1;
|
||||||
|
end;
|
||||||
|
static function operator implicit<T>(a: t2<t2<t2<T>>>): t1; where T: record;
|
||||||
|
begin
|
||||||
|
i := 2;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
var a: t0<t0<byte>>;
|
||||||
|
var a2: t2<t2<t2<byte>>>;
|
||||||
|
var k: t1 := a;
|
||||||
|
assert(i = 1);
|
||||||
|
k := a2;
|
||||||
|
assert(i = 2);
|
||||||
|
end.
|
||||||
25
TestSuite/implicitexplicit20.pas
Normal file
25
TestSuite/implicitexplicit20.pas
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
var i: integer;
|
||||||
|
type
|
||||||
|
TRec = record end;
|
||||||
|
t0<T> = class end;
|
||||||
|
t2<T> = class end;
|
||||||
|
t1 = class
|
||||||
|
|
||||||
|
static function operator implicit<T>(a: t0<t0<T>>): t1; where T: record;
|
||||||
|
begin
|
||||||
|
i := 1;
|
||||||
|
end;
|
||||||
|
static function operator implicit<T>(a: t2<t2<t2<T>>>): t1; where T: record;
|
||||||
|
begin
|
||||||
|
i := 2;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
var a: t0<t0<TRec>>;
|
||||||
|
var a2: t2<t2<t2<TRec>>>;
|
||||||
|
var k: t1 := a;
|
||||||
|
assert(i = 1);
|
||||||
|
k := a2;
|
||||||
|
assert(i = 2);
|
||||||
|
end.
|
||||||
20
TestSuite/implicitexplicit21.pas
Normal file
20
TestSuite/implicitexplicit21.pas
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
var i: integer;
|
||||||
|
type
|
||||||
|
Generic1<T> = class end;
|
||||||
|
Generic2<T1,T2> = class end;
|
||||||
|
|
||||||
|
ConvTarget = class
|
||||||
|
|
||||||
|
static function operator implicit<T1, T2>(o: Generic2<T1, Generic1<T2>>): ConvTarget; where T1, T2: record;
|
||||||
|
begin
|
||||||
|
Result := new ConvTarget;
|
||||||
|
i := 1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
var a: Generic2<byte, Generic1<word>>;
|
||||||
|
var o: ConvTarget := a;
|
||||||
|
assert(i = 1);
|
||||||
|
end.
|
||||||
|
|
@ -2375,7 +2375,20 @@ namespace PascalABCCompiler.TreeRealization
|
||||||
if (fn.parameters[0].type.is_generic_parameter)
|
if (fn.parameters[0].type.is_generic_parameter)
|
||||||
fn = fn.get_instance(new List<type_node>() { this }, false, null);
|
fn = fn.get_instance(new List<type_node>() { this }, false, null);
|
||||||
else
|
else
|
||||||
fn = fn.get_instance(this.instance_params, false, null);
|
{
|
||||||
|
var expr_list = new expressions_list();
|
||||||
|
expr_list.AddElement(new default_operator_node(ctn, fn.location));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fn = generic_convertions.DeduceFunction(fn, expr_list, true, compilation_context.instance, fn.location);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
if (fn != null && !fn.is_generic_function_instance)
|
||||||
|
fn = null;
|
||||||
|
}
|
||||||
if (fn == null)
|
if (fn == null)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -2387,9 +2400,18 @@ namespace PascalABCCompiler.TreeRealization
|
||||||
{
|
{
|
||||||
if (ctn.IsPointer)
|
if (ctn.IsPointer)
|
||||||
continue;
|
continue;
|
||||||
if (ctn.type_special_kind == SemanticTree.type_special_kind.array_kind)
|
var expr_list = new expressions_list();
|
||||||
ctn = ctn.element_type;
|
expr_list.AddElement(new default_operator_node(ctn, fn.location));
|
||||||
fn = fn.get_instance(new List<type_node>(new type_node[] { ctn }), false, null);
|
try
|
||||||
|
{
|
||||||
|
fn = generic_convertions.DeduceFunction(fn, expr_list, true, compilation_context.instance, fn.location);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
if (fn != null && !fn.is_generic_function_instance)
|
||||||
|
fn = null;
|
||||||
if (fn == null)
|
if (fn == null)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -2425,19 +2447,38 @@ namespace PascalABCCompiler.TreeRealization
|
||||||
if (fn.parameters[0].type.is_generic_parameter)
|
if (fn.parameters[0].type.is_generic_parameter)
|
||||||
fn = fn.get_instance(new List<type_node>() { ctn }, false, null);
|
fn = fn.get_instance(new List<type_node>() { ctn }, false, null);
|
||||||
else
|
else
|
||||||
fn = fn.get_instance(ctn.instance_params, false, null);
|
{
|
||||||
|
var expr_list = new expressions_list();
|
||||||
|
expr_list.AddElement(new default_operator_node(ctn, fn.location));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fn = generic_convertions.DeduceFunction(fn, expr_list, true, compilation_context.instance, fn.location);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
if (fn != null && !fn.is_generic_function_instance)
|
||||||
|
fn = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (fn == null)
|
if (fn == null)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (fn.get_generic_params_list() != null && fn.get_generic_params_list().Count > 0)
|
else if (fn.get_generic_params_list() != null && fn.get_generic_params_list().Count > 0)
|
||||||
{
|
{
|
||||||
if (ctn is ref_type_node && !fn.parameters[0].type.is_generic_parameter)
|
var expr_list = new expressions_list();
|
||||||
ctn = (ctn as ref_type_node).pointed_type;
|
expr_list.AddElement(new default_operator_node(ctn, fn.location));
|
||||||
if (ctn.IsPointer)
|
try
|
||||||
continue;
|
{
|
||||||
if (ctn.type_special_kind == SemanticTree.type_special_kind.array_kind)
|
fn = generic_convertions.DeduceFunction(fn, expr_list, true, compilation_context.instance, fn.location);
|
||||||
ctn = ctn.element_type;
|
}
|
||||||
fn = fn.get_instance(new List<type_node>(new type_node[] { ctn }), false, null);
|
catch
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
if (fn != null && !fn.is_generic_function_instance)
|
||||||
|
fn = null;
|
||||||
if (fn == null)
|
if (fn == null)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue