Generic functions with nested function and result variable collision

Summary

When I tried to use a nested function in a generic function I get a duplicate identifier $result error.

System Information

  • Operating system: Linux, AlmaLinux 9.1, X86_64
  • Processor architecture: X86_64, 64 bit
  • Compiler version: 3.3.1-12327-gb997e413
  • Device: Computer

Steps to reproduce

Given the following program:

program gnr;

function booNG (const a: string): string;
  function nested: string;
    begin
      result := 'ng boo! ' + a;
    end;

  begin
    result := nested;
  end;

generic function boo<T> (const a: T): T;
  function nested: string;
    begin
      result := 'g boo!' + a;
    end;

  begin
    result := nested;
  end;

begin
  writeln(booNG('rabbit'));
  writeln(boo('rabbit'));
end.
// CudaText: lexer_file=Pascal; tab_size=2; tab_spaces=Yes; newline=LF;

When I attempt to compile it, I get:

$ /home/dev/fpc_usr/bin/fpc -Mobjfpc -Sh -MfunctionReferences -ManonymousFunctions -MimplicitFunctionSpecialization -OoUnusedPara -vewnh -Sewnh -gh -gl -gp -gw3 -Xg -Xi -Sm -Sg -Os -Si -MadvancedRecords -McVar -OoPeepHole -OoTailRec -OoRemoveEmptyProcs -OoConstProp -OoDFA -OoCSE -OoDeadStore -OoDeadValues genericnestedreturn.pas
Hint: Start of reading config file /home/dev/fpc_usr/lib/fpc/etc/fpc.cfg
Hint: End of reading config file /home/dev/fpc_usr/lib/fpc/etc/fpc.cfg
Free Pascal Compiler version 3.3.1 [2023/01/10] for x86_64
Copyright (c) 1993-2023 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling genericnestedreturn.pas
genericnestedreturn.pas(15,5) Error: Duplicate identifier "$result"
genericnestedreturn.pas(15,5) Hint: (treated as error) Identifier already defined in unit GNR: genericnestedreturn.pas at line 14
genericnestedreturn.pas(28) Fatal: There were 2 errors compiling module, stopping
Fatal: Compilation aborted
Error: /home/dev/fpc_usr/lib/fpc/3.3.1/ppcx64 returned an error exitcode

Example Project

See Steps to reproduce.

What is the current bug behavior?

The compiler says that the result of the nested function is a duplicate.

What is the expected (correct) behavior?

That the compiler allow the nested function.

Why? The following programs compile and run correctly:

program anr;

function booNG (const a: string): string;
  function nested: string;
    begin
      result := 'boo! ' + a;
    end;

  begin
    result := nested;
  end;

function booNG2 (const a: string): integer;
  function nested: string;
    begin
      result := 'boo! ' + a;
    end;

  begin
    result := length(nested);
  end;


begin
  writeln(booNG('rabbit'));
  writeln(booNG2('rabbit'));
end.
// CudaText: lexer_file=Pascal; tab_size=2; tab_spaces=Yes; newline=LF;

When compiled and ran:

$ /home/dev/fpc_usr/bin/fpc -Mobjfpc -Sh -MfunctionReferences -ManonymousFunctions -MimplicitFunctionSpecialization -OoUnusedPara -vewnh -Sewnh -gh -gl -gp -gw3 -Xg -Xi -Sm -Sg -Os -Si -MadvancedRecords -McVar -OoPeepHole -OoTailRec -OoRemoveEmptyProcs -OoConstProp -OoDFA -OoCSE -OoDeadStore -OoDeadValues anestedreturn.pas
Hint: Start of reading config file /home/dev/fpc_usr/lib/fpc/etc/fpc.cfg
Hint: End of reading config file /home/dev/fpc_usr/lib/fpc/etc/fpc.cfg
Free Pascal Compiler version 3.3.1 [2023/01/10] for x86_64
Copyright (c) 1993-2023 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling anestedreturn.pas
Linking anestedreturn
28 lines compiled, 0.1 sec, 169040 bytes code, 1144192 bytes data
2 hint(s) issued

$ ./anestedreturn
boo! rabbit
11
Heap dump by heaptrc unit of "/home/dev/das_misc/fpc-issues/generic-nested-result/anestedreturn"
2 memory blocks allocated : 56/64
2 memory blocks freed     : 56/64
0 unfreed memory blocks : 0
True heap size : 32768
True free heap : 32768
program agnnr;

function booNG (const a: string): string;
  function nested: string;
    begin
      result := 'ng boo! ' + a;
    end;

  begin
    result := nested;
  end;

generic function boo<T> (const a: T): T;
  begin
    result := 'g boo! ' + a;
  end;


begin
  writeln(booNG('rabbit'));
  writeln(boo('rabbit'));
end.
// CudaText: lexer_file=Pascal; tab_size=2; tab_spaces=Yes; newline=LF;

When compiled and ran:

$ /home/dev/fpc_usr/bin/fpc -Mobjfpc -Sh -MfunctionReferences -ManonymousFunctions -MimplicitFunctionSpecialization -OoUnusedPara -vewnh -Sewnh -gh -gl -gp -gw3 -Xg -Xi -Sm -Sg -Os -Si -MadvancedRecords -McVar -OoPeepHole -OoTailRec -OoRemoveEmptyProcs -OoConstProp -OoDFA -OoCSE -OoDeadStore -OoDeadValues agenericnonnestedreturn.pas
Hint: Start of reading config file /home/dev/fpc_usr/lib/fpc/etc/fpc.cfg
Hint: End of reading config file /home/dev/fpc_usr/lib/fpc/etc/fpc.cfg
Free Pascal Compiler version 3.3.1 [2023/01/10] for x86_64
Copyright (c) 1993-2023 by Florian Klaempfl and others
Target OS: Linux for x86-64
Compiling agenericnonnestedreturn.pas
Linking agenericnonnestedreturn
23 lines compiled, 0.1 sec, 168912 bytes code, 1144224 bytes data
2 hint(s) issued

$ ./agenericnonnestedreturn
ng boo! rabbit
g boo! rabbit
Heap dump by heaptrc unit of "/home/dev/das_misc/fpc-issues/generic-nested-result/agenericnonnestedreturn"
1 memory blocks allocated : 31/32
1 memory blocks freed     : 31/32
0 unfreed memory blocks : 0
True heap size : 32768
True free heap : 32768

Relevant logs and/or screenshots

See the Steps to reproduce section.

Possible fixes

I do not know of any.

Other

I found this issue #38216 but it does not appear to be related, even though the subject seems similar.

Edited by bogen85