2
0
Эх сурвалжийг харах

* handle usage of generics type as class type correctly, resolves #16065

git-svn-id: trunk@15157 -
florian 15 жил өмнө
parent
commit
62c630abce

+ 1 - 0
.gitattributes

@@ -10341,6 +10341,7 @@ tests/webtbs/tw1592.pp svneol=native#text/plain
 tests/webtbs/tw15930.pp svneol=native#text/plain
 tests/webtbs/tw16004.pp svneol=native#text/plain
 tests/webtbs/tw16040.pp svneol=native#text/plain
+tests/webtbs/tw16065.pp svneol=native#text/pascal
 tests/webtbs/tw16083.pp svneol=native#text/plain
 tests/webtbs/tw16108.pp svneol=native#text/plain
 tests/webtbs/tw16161.pp svneol=native#text/pascal

+ 11 - 1
compiler/nmem.pas

@@ -159,7 +159,17 @@ implementation
           classrefdef :
             resultdef:=left.resultdef;
           objectdef :
-            resultdef:=tclassrefdef.create(left.resultdef);
+            { access to the classtype while specializing? }
+            if (df_generic in left.resultdef.defoptions) and
+              assigned(current_objectdef.genericdef) then
+              begin
+                if current_objectdef.genericdef=left.resultdef then
+                  resultdef:=tclassrefdef.create(current_objectdef)
+                else
+                  message(parser_e_cant_create_generics_of_this_type);
+              end
+            else
+              resultdef:=tclassrefdef.create(left.resultdef);
           else
             Message(parser_e_pointer_to_class_expected);
         end;

+ 26 - 0
tests/webtbs/tw16065.pp

@@ -0,0 +1,26 @@
+{$mode objfpc}
+
+type
+  generic TGen<_T> = class
+  public
+    function Check(ASource: TObject): Boolean;
+  end;
+
+  TSpec = specialize TGen<Integer>;
+
+function TGen.Check(ASource: TObject): Boolean;
+begin
+  Result := (ASource is TGen)   // this line breaks the compiler...
+  and (ASource is ClassType);   // ...it should be equivelent to this line
+end;
+
+var
+  f:  TSpec;
+  o: TObject;
+begin
+  f := TSpec.Create;
+  o := TObject.Create;
+  if not(f.Check(f)) or f.Check(o) then
+    halt(1);
+  writeln('ok');
+end.