Skip to content

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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information