Skip to content

Compile error from Clang when passing a procedural type with var return type #25870

Description

@demotomohiro

Nim Version

Nim Compiler Version 2.3.1 [Linux: arm64]
Compiled at 2026-06-02
Copyright (c) 2006-2026 by Andreas Rumpf

git hash: 73986c0
active boot switches: -d:release

Description

Compiling following code with nim cpp --cc:clang generates compile error from clang:

proc testVarRet(x: var int): var int = x

proc testProcTypeParam(prc: proc (x: var int): var int {.nimcall.}) = discard

testProcTypeParam(testVarRet)

It compiles without error when compiled with nim c or compiled without clang backend.

Current Output

testvarret/debug/@mtestvarret.nim.cpp:119:56: error: no matching function for call to 'testProcTypeParam__testvarret_u23'
  119 |         nimlf_(5, "testvarret.nim");testProcTypeParam__testvarret_u23(testVarRet__testvarret_u1);
      |                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
testvarret/debug/@mtestvarret.nim.cpp:73:31: note: candidate function not viable: no known conversion from 'NI *(NI &)' (aka 'long *(long &)') to 'tyProc__6ZQ0ZDxLqdLoyCLmNo1XEw' (aka 'long &(*)(long &)') for 1st argument
   73 | N_LIB_PRIVATE N_NIMCALL(void, testProcTypeParam__testvarret_u23)(tyProc__6ZQ0ZDxLqdLoyCLmNo1XEw prc_p0) {
      |                               ^                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Nim/lib/nimbase.h:254:44: note: expanded from macro 'N_NIMCALL'
  254 | #  define N_NIMCALL(rettype, name) rettype name /* no modifier */
      |
1 error generated.

Expected Output

compiles without errors

Known Workarounds

No response

Additional Information

When Nim compiled above code with nim cpp, it generates code like this:

typedef int& (tyProc)(int& x_p0);

int* testVarRet(int& x) {
  return &x;
}

void testProcTypeParam(tyProc prc) {
}

int main()
{
  testProcTypeParam(testVarRet);
}

The type of testVarRet is int* (*)(int&) and it is converted to type int& (*)(int&) when it is passed to testProcTypeParam.
gcc compiles this code without error with -fpermissive flag.
But clang generates compile error even if it is compiled with -fpermissive flag.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions