Browse Source

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

git-svn-id: trunk@47795 -

svenbarth 4 years ago
parent
commit
d29f95d9e1
4 changed files with 49 additions and 1 deletions
  1. 2 0
      .gitattributes
  2. 1 1
      compiler/ptype.pas
  3. 23 0
      tests/test/tgeneric106.pp
  4. 23 0
      tests/test/tgeneric107.pp

+ 2 - 0
.gitattributes

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

+ 1 - 1
compiler/ptype.pas

@@ -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 - 0
tests/test/tgeneric106.pp

@@ -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 - 0
tests/test/tgeneric107.pp

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