mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 17:47:56 +02:00
* generate an error if the type parameters of the record, object or class do not match with its declaration
+ added test git-svn-id: trunk@39702 -
This commit is contained in:
parent
03a036c6cb
commit
50323043c1
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -13076,6 +13076,7 @@ tests/test/tgeneric101.pp svneol=native#text/pascal
|
||||
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/tgeneric11.pp svneol=native#text/plain
|
||||
tests/test/tgeneric12.pp svneol=native#text/plain
|
||||
tests/test/tgeneric13.pp svneol=native#text/plain
|
||||
|
@ -856,6 +856,34 @@ implementation
|
||||
sp:='';
|
||||
end;
|
||||
|
||||
function check_generic_parameters(def:tstoreddef):boolean;
|
||||
var
|
||||
i : longint;
|
||||
decltype,
|
||||
impltype : ttypesym;
|
||||
implname : tsymstr;
|
||||
begin
|
||||
result:=true;
|
||||
if not assigned(def.genericparas) then
|
||||
internalerror(2018090102);
|
||||
if not assigned(genericparams) then
|
||||
internalerror(2018090103);
|
||||
if def.genericparas.count<>genericparams.count then
|
||||
internalerror(2018090104);
|
||||
for i:=0 to def.genericparas.count-1 do
|
||||
begin
|
||||
decltype:=ttypesym(def.genericparas[i]);
|
||||
impltype:=ttypesym(genericparams[i]);
|
||||
implname:=upper(genericparams.nameofindex(i));
|
||||
if decltype.name<>implname then
|
||||
begin
|
||||
messagepos1(impltype.fileinfo,sym_e_generic_type_param_mismatch,impltype.realname);
|
||||
messagepos1(decltype.fileinfo,sym_e_generic_type_param_decl,decltype.realname);
|
||||
result:=false;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
sp:='';
|
||||
orgsp:='';
|
||||
@ -952,6 +980,17 @@ implementation
|
||||
srsym:=search_object_name(sp,true);
|
||||
current_filepos:=oldfilepos;
|
||||
|
||||
{ we need to check whether the names of the generic parameter
|
||||
types match with the one in the declaration of a class/record,
|
||||
but we need to do this before consume_proc_name frees the
|
||||
type parameters of the class part }
|
||||
if (srsym.typ=typesym) and
|
||||
(ttypesym(srsym).typedef.typ in [objectdef,recorddef]) and
|
||||
tstoreddef(ttypesym(srsym).typedef).is_generic and
|
||||
assigned(genericparams) then
|
||||
{ this is recoverable, so no further action necessary }
|
||||
check_generic_parameters(tstoreddef(ttypesym(srsym).typedef));
|
||||
|
||||
{ consume proc name }
|
||||
procstartfilepos:=current_tokenpos;
|
||||
consume_proc_name;
|
||||
|
22
tests/test/tgeneric105.pp
Normal file
22
tests/test/tgeneric105.pp
Normal file
@ -0,0 +1,22 @@
|
||||
{ %FAIL }
|
||||
|
||||
{ the type parameters of the implementation need to match those in the interface }
|
||||
unit tgeneric105;
|
||||
|
||||
{$mode delphi}
|
||||
|
||||
interface
|
||||
|
||||
type
|
||||
TTest<T> = class
|
||||
procedure Test;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
procedure TTest<S>.Test;
|
||||
begin
|
||||
end;
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user