Переглянути джерело

* fix for Mantis #31973: resolve dummy symbols earlier and print a nice error message if a generic dummy could not be resolved to an ordinary symbol
+ added test
* adjusted test tw9673 which should have never worked as is (what if TList would have been "of T" instead of "of byte"?)

git-svn-id: trunk@36468 -

svenbarth 8 роки тому
батько
коміт
eb9b4fb71f
4 змінених файлів з 65 додано та 3 видалено
  1. 1 0
      .gitattributes
  2. 39 1
      compiler/pexpr.pas
  3. 23 0
      tests/webtbf/tw31973.pp
  4. 2 2
      tests/webtbs/tw9673.pp

+ 1 - 0
.gitattributes

@@ -14000,6 +14000,7 @@ tests/webtbf/tw3145.pp svneol=native#text/plain
 tests/webtbf/tw31465.pp svneol=native#text/pascal
 tests/webtbf/tw3183.pp svneol=native#text/plain
 tests/webtbf/tw3186.pp svneol=native#text/plain
+tests/webtbf/tw31973.pp svneol=native#text/pascal
 tests/webtbf/tw3218.pp svneol=native#text/plain
 tests/webtbf/tw3241.pp svneol=native#text/plain
 tests/webtbf/tw3253.pp svneol=native#text/plain

+ 39 - 1
compiler/pexpr.pas

@@ -2760,6 +2760,7 @@ implementation
            storedpattern: string;
            callflags: tcallnodeflags;
            t : ttoken;
+           wasgenericdummy,
            allowspecialize,
            isspecialize,
            unit_found : boolean;
@@ -2891,6 +2892,40 @@ implementation
                      end;
                  end;
 
+               wasgenericdummy:=false;
+               if assigned(srsym) and
+                   (sp_generic_dummy in srsym.symoptions) and
+                   (
+                     (
+                       (m_delphi in current_settings.modeswitches) and
+                       not (token in [_LT, _LSHARPBRACKET]) and
+                       (srsym.typ=typesym) and
+                       (ttypesym(srsym).typedef.typ=undefineddef)
+                     )
+                     or
+                     (
+                       not (m_delphi in current_settings.modeswitches) and
+                       not isspecialize and
+                       (
+                         not parse_generic or
+                         not (
+                           assigned(current_structdef) and
+                           assigned(get_generic_in_hierarchy_by_name(srsym,current_structdef))
+                         )
+                       )
+                     )
+                   ) then
+                 begin
+                   srsym:=resolve_generic_dummysym(srsym.name);
+                   if assigned(srsym) then
+                     srsymtable:=srsym.owner
+                   else
+                     begin
+                       srsymtable:=nil;
+                       wasgenericdummy:=true;
+                     end;
+                 end;
+
                { check hints, but only if it isn't a potential generic symbol;
                  that is checked in sub_expr if it isn't a generic }
                if assigned(srsym) and
@@ -2943,7 +2978,10 @@ implementation
                      end
                    else
                      begin
-                       identifier_not_found(orgstoredpattern,tokenpos);
+                       if wasgenericdummy then
+                         messagepos(tokenpos,parser_e_no_generics_as_types)
+                       else
+                         identifier_not_found(orgstoredpattern,tokenpos);
                        srsym:=generrorsym;
                        srsymtable:=nil;
                      end;

+ 23 - 0
tests/webtbf/tw31973.pp

@@ -0,0 +1,23 @@
+{ %FAIL }
+
+program tw31973;
+
+{$mode objfpc}{$H+}
+
+uses
+  Classes, SysUtils
+  { you can add units after this },
+  gutil, gset;
+
+type
+  TIntegerSetCompare = specialize TLess<Integer>;
+  TIntegerSet = specialize TSet<Integer, TIntegerSetCompare>;
+
+var
+  ISet: TIntegerSet;
+  I: Integer;
+  Iterator: TSet.TIterator; //should be TIntegerSet.TIterator;
+begin
+  ISet := TIntegerSet.Create();
+  Iterator := ISet.Find(42); //error2014052306.lpr(20,12) Error: Internal error 2014052306
+end.

+ 2 - 2
tests/webtbs/tw9673.pp

@@ -12,9 +12,9 @@ type
   end;
 	    
 var
-  b : Testclass.TList;
+  b : specialize Testclass<LongInt>.TList;
 	      
 	    
 implementation
 begin
-end.
+end.