* apply patch by Blaise.ru to allow specializations for the result type of function and method variables

+ added tests

git-svn-id: trunk@47795 -
This commit is contained in:
svenbarth 2020-12-16 21:43:30 +00:00
parent 32938dde1c
commit d29f95d9e1
4 changed files with 49 additions and 1 deletions

2
.gitattributes vendored
View File

@ -15063,6 +15063,8 @@ tests/test/tgeneric102.pp svneol=native#text/pascal
tests/test/tgeneric103.pp svneol=native#text/pascal
tests/test/tgeneric104.pp -text svneol=native#text/pascal
tests/test/tgeneric105.pp svneol=native#text/pascal
tests/test/tgeneric106.pp svneol=native#text/pascal
tests/test/tgeneric107.pp svneol=native#text/pascal
tests/test/tgeneric11.pp svneol=native#text/plain
tests/test/tgeneric12.pp svneol=native#text/plain
tests/test/tgeneric13.pp svneol=native#text/plain

View File

@ -1587,7 +1587,7 @@ implementation
if is_func then
begin
consume(_COLON);
single_type(pd.returndef,[]);
single_type(pd.returndef,[stoAllowSpecialization]);
end;
if try_to_consume(_OF) then
begin

23
tests/test/tgeneric106.pp Normal file
View File

@ -0,0 +1,23 @@
program tgeneric106;
{$Mode Delphi}
type G<T> = class
var X: T;
// EXPECTED: gets compiled
// ACTUAL: 'Error: Generics without specialization cannot be used as a type for a variable'
class var F: function(const X: T) : G<T> of object;
function Foo(const X: T): G<T>;
end;
function G<T>.Foo(const X: T): G<T>;
begin
result := G<T>.Create;
result.X := X
end;
begin
G<Integer>.F := G<Integer>.Create.Foo;
if G<Integer>.F(42).X <> 42 then
halt(1);
end.

23
tests/test/tgeneric107.pp Normal file
View File

@ -0,0 +1,23 @@
program tgeneric107;
{$Mode ObjFpc}
type generic G<T> = class
var X: T;
// EXPECTED: gets compiled
// ACTUAL: 'Error: Generics without specialization cannot be used as a type for a variable'
class var F: function(const X: T) : specialize G<T> of object;
function Foo(const aX: T): specialize G<T>;
end;
function G.Foo(const aX: T): specialize G<T>;
begin
result := specialize G<T>.Create;
result.X := aX
end;
begin
specialize G<Integer>.F := @specialize G<Integer>.Create.Foo;
if specialize G<Integer>.F(42).X <> 42 then
halt(1);
end.