浏览代码

Allow the usage of type aliases of generic type parameters outside of the generic. Besides being useful by itself it will also be needed in the future when the visibility of the type parameters is changed from public to strict private.

ptype.pas, id_type:
  * don't generate an error if the undefineddef typesym is an explicit rename that belongs to a generic

+ added test

git-svn-id: trunk@29485 -
svenbarth 10 年之前
父节点
当前提交
a4e8f00399
共有 3 个文件被更改,包括 56 次插入1 次删除
  1. 1 0
      .gitattributes
  2. 5 1
      compiler/ptype.pas
  3. 50 0
      tests/test/tgeneric98.pp

+ 1 - 0
.gitattributes

@@ -11710,6 +11710,7 @@ tests/test/tgeneric94.pp svneol=native#text/pascal
 tests/test/tgeneric95.pp svneol=native#text/pascal
 tests/test/tgeneric95.pp svneol=native#text/pascal
 tests/test/tgeneric96.pp svneol=native#text/pascal
 tests/test/tgeneric96.pp svneol=native#text/pascal
 tests/test/tgeneric97.pp svneol=native#text/pascal
 tests/test/tgeneric97.pp svneol=native#text/pascal
+tests/test/tgeneric98.pp svneol=native#text/pascal
 tests/test/tgoto.pp svneol=native#text/plain
 tests/test/tgoto.pp svneol=native#text/plain
 tests/test/theap.pp svneol=native#text/plain
 tests/test/theap.pp svneol=native#text/plain
 tests/test/theapthread.pp svneol=native#text/plain
 tests/test/theapthread.pp svneol=native#text/plain

+ 5 - 1
compiler/ptype.pas

@@ -340,7 +340,11 @@ implementation
             ((ttypesym(srsym).typedef.typ=errordef) or
             ((ttypesym(srsym).typedef.typ=errordef) or
             (not allowgenericsyms and
             (not allowgenericsyms and
             (ttypesym(srsym).typedef.typ=undefineddef) and
             (ttypesym(srsym).typedef.typ=undefineddef) and
-            not (sp_generic_para in srsym.symoptions))) then
+            not (sp_generic_para in srsym.symoptions) and
+            not (sp_explicitrename in srsym.symoptions) and
+            not assigned(srsym.owner.defowner) and
+            { use df_generic instead of is_generic to allow aliases in nested types as well }
+            not (df_generic in tstoreddef(srsym.owner.defowner).defoptions))) then
           begin
           begin
             Message1(type_e_type_is_not_completly_defined,ttypesym(srsym).realname);
             Message1(type_e_type_is_not_completly_defined,ttypesym(srsym).realname);
             def:=generrordef;
             def:=generrordef;

+ 50 - 0
tests/test/tgeneric98.pp

@@ -0,0 +1,50 @@
+{ %NORUN }
+
+program tgeneric98;
+
+{$mode objfpc}
+
+type
+  generic TTest<T> = class
+  public type
+    TAlias = T;
+  private
+    fField: TAlias;
+    procedure SetField(aValue: TAlias);
+  public
+    property Field: TAlias read fField write SetField;
+    function CalcField: TAlias;
+  end;
+
+  generic TTest2<T> = class
+  public type
+    TTestT = specialize TTest<T>;
+  private
+    fField: TTestT.TAlias;
+    procedure SetField(aValue: TTestT.TAlias);
+  public
+    property Field: TTestT.TAlias read fField write SetField;
+    function CalcField: TTestT.TAlias;
+  end;
+
+procedure TTest.SetField(aValue: TAlias);
+begin
+end;
+
+function TTest.CalcField: TAlias;
+begin
+  Result := Default(TAlias);
+end;
+
+procedure TTest2.SetField(aValue: TTestT.TAlias);
+begin
+end;
+
+function TTest2.CalcField: TTestT.TAlias;
+begin
+  Result := Default(TTestT.TAlias);
+end;
+
+begin
+
+end.