mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 13:29:14 +02:00
* fix #39681: also handle the result type of a specialized procvar when checking for a possible implicit specialization
+ added test
This commit is contained in:
parent
c0fa45dc92
commit
76753438ed
@ -923,6 +923,30 @@ uses
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handle_procvars(genericparams:tfphashlist;callerparams:tfplist;target_def:tdef;caller_def:tdef):boolean;
|
function handle_procvars(genericparams:tfphashlist;callerparams:tfplist;target_def:tdef;caller_def:tdef):boolean;
|
||||||
|
var
|
||||||
|
newparams : tfphashlist;
|
||||||
|
|
||||||
|
procedure handle_generic_param(targetparadef,callerparadef:tdef);
|
||||||
|
var
|
||||||
|
key : string;
|
||||||
|
index : integer;
|
||||||
|
begin
|
||||||
|
if not assigned(callerparadef.typesym) then
|
||||||
|
internalerror(2021020908);
|
||||||
|
|
||||||
|
key:=generic_param_hash(targetparadef);
|
||||||
|
|
||||||
|
{ the generic param must not already be used }
|
||||||
|
index:=genericparams.findindexof(key);
|
||||||
|
if index<0 then
|
||||||
|
begin
|
||||||
|
{ add the type to the list }
|
||||||
|
index:=newparams.findindexof(key);
|
||||||
|
if index<0 then
|
||||||
|
newparams.add(key,callerparadef.typesym);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
i,j : integer;
|
i,j : integer;
|
||||||
paravar : tparavarsym;
|
paravar : tparavarsym;
|
||||||
@ -930,9 +954,6 @@ uses
|
|||||||
caller_proc : tprocvardef;
|
caller_proc : tprocvardef;
|
||||||
target_proc_para,
|
target_proc_para,
|
||||||
caller_proc_para : tparavarsym;
|
caller_proc_para : tparavarsym;
|
||||||
newparams : tfphashlist;
|
|
||||||
key : string;
|
|
||||||
index : integer;
|
|
||||||
valid_params : integer;
|
valid_params : integer;
|
||||||
begin
|
begin
|
||||||
result := false;
|
result := false;
|
||||||
@ -977,28 +998,27 @@ uses
|
|||||||
{ find the generic param name in the generic def parameters }
|
{ find the generic param name in the generic def parameters }
|
||||||
j:=target_proc.genericdef.genericparas.findindexof(paravar.vardef.typesym.name);
|
j:=target_proc.genericdef.genericparas.findindexof(paravar.vardef.typesym.name);
|
||||||
|
|
||||||
target_def:=ttypesym(target_proc.genericparas[j]).typedef;
|
handle_generic_param(ttypesym(target_proc.genericparas[j]).typedef,caller_proc_para.vardef);
|
||||||
caller_def:=caller_proc_para.vardef;
|
|
||||||
|
|
||||||
if not assigned(caller_def.typesym) then
|
|
||||||
internalerror(2021020908);
|
|
||||||
|
|
||||||
key:=generic_param_hash(target_def);
|
|
||||||
|
|
||||||
{ the generic param must not already be used }
|
|
||||||
index:=genericparams.findindexof(key);
|
|
||||||
if index<0 then
|
|
||||||
begin
|
|
||||||
{ add the type to the list }
|
|
||||||
index:=newparams.findindexof(key);
|
|
||||||
if index<0 then
|
|
||||||
newparams.add(key,caller_def.typesym);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
inc(valid_params);
|
inc(valid_params);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
if assigned(target_proc.returndef) and not is_void(target_proc.returndef) then
|
||||||
|
begin
|
||||||
|
{ or check for exact? }
|
||||||
|
if compare_defs(caller_proc.returndef,target_proc.returndef,nothingn)<te_equal then
|
||||||
|
begin
|
||||||
|
newparams.free;
|
||||||
|
exit(false);
|
||||||
|
end;
|
||||||
|
|
||||||
|
if sp_generic_para in target_proc.returndef.typesym.symoptions then
|
||||||
|
begin
|
||||||
|
handle_generic_param(target_proc.returndef,caller_proc.returndef);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ if the count of valid params matches the target then
|
{ if the count of valid params matches the target then
|
||||||
transfer the temporary params to the actual params }
|
transfer the temporary params to the actual params }
|
||||||
result:=valid_params=target_proc.paras.count;
|
result:=valid_params=target_proc.paras.count;
|
||||||
|
23
tests/webtbs/tw39681.pp
Normal file
23
tests/webtbs/tw39681.pp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{ %NORUN }
|
||||||
|
|
||||||
|
program tw39681;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
{$ModeSwitch implicitfunctionspecialization}
|
||||||
|
|
||||||
|
type
|
||||||
|
generic TFunc<TResult> = function: TResult;
|
||||||
|
|
||||||
|
generic procedure Bar<T>(f: specialize TFunc<T>);
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
function Foo: Integer;
|
||||||
|
begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
specialize Bar<Integer>(@Foo); // works
|
||||||
|
Bar(@Foo); // Error
|
||||||
|
end.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user