I want declare only signature of function and build body code by CTFE.

module mdl;
import std.stdio;
import std.traits;
import std.string;

enum autofnc;

@autofnc
{
        int foo(int);
        int bar(int);
}

void main()
{
        writeln(foo(12));
}

mixin cfuncR;

mixin template cfuncR()
{
        mixin impl!(getSymbolsByUDA!(mdl, autofnc));

        mixin template impl(funcs...)
        {
                static if (funcs.length == 1)
                {
                        mixin("pragma(msg, typeof(%1$s)); // !!! here I get 
_error_
ReturnType!%1$s %1$s(Parameters!%1$s vals) { return vals[0] * 2; }".format(__traits(identifier, funcs[0]));
                }
                else
                {
                        mixin impl!(funcs[0..$/2]);
                        mixin impl!(funcs[$/2..$]);
                }
        }
}

I get this output:

/usr/include/dmd/phobos/std/traits.d-mixin-7671(7671): Deprecation: mdl.object is not visible from module traits /usr/include/dmd/phobos/std/traits.d-mixin-7671(7671): Deprecation: mdl.std is not visible from module traits mdl.d-mixin-29(30): Error: template instance std.traits.ReturnType!(foo) does not match template declaration ReturnType(func...) if (func.length == 1 && isCallable!func) mdl.d-mixin-29(30): Error: template instance Parameters!foo does not match template declaration Parameters(func...) if (func.length == 1 && isCallable!func)
_error_
mdl.d(34): Error: mixin mdl.cfuncR!().impl!(foo, bar).impl!(foo) error instantiating mdl.d-mixin-29(30): Error: template instance std.traits.ReturnType!(bar) does not match template declaration ReturnType(func...) if (func.length == 1 && isCallable!func) mdl.d-mixin-29(30): Error: template instance Parameters!bar does not match template declaration Parameters(func...) if (func.length == 1 && isCallable!func)
_error_
mdl.d(35): Error: mixin mdl.cfuncR!().impl!(foo, bar).impl!(bar) error instantiating mdl.d(23): Error: mixin mdl.cfuncR!().impl!(foo, bar) error instantiating
mdl.d(19): Error: mixin mdl.cfuncR!() error instantiating
Failed: ["dmd", "-v", "-o-", "mdl.d", "-I."]

I think 'template instance std.traits.ReturnType!(foo) does not match template declaration' because 'foo' is '_error_' on it's instancing moment. But I don't understand why 'foo' is '_error_'.

But if I replace '%1$s' in building function name to '_%1$s' pragma(msg, foo) works normal and compiler behavior is predictable (defined '_foo', but 'foo' has no body and can't linked):

/usr/include/dmd/phobos/std/traits.d-mixin-7671(7671): Deprecation: mdl.object is not visible from module traits /usr/include/dmd/phobos/std/traits.d-mixin-7671(7671): Deprecation: mdl.std is not visible from module traits
int(int)
int(int)
/usr/include/dmd/phobos/std/traits.d-mixin-7671(7671): Deprecation: mdl.object is not visible from module traits /usr/include/dmd/phobos/std/traits.d-mixin-7671(7671): Deprecation: mdl.std is not visible from module traits
int(int)
int(int)
/tmp/.rdmd-1000/rdmd-mdl.d-9F3ADBC813DCE463C0EFA2CA038B009E/objs/mdl.o: In 
function `_Dmain':
mdl.d:(.text._Dmain+0xa): undefined reference to `_D3mdl3fooFiZi'
collect2: error: ld returned 1 exit status
Error: linker exited with status 1

But if I wrote this code by hands:

ReturnType!foo foo(Parameters!foo vals) { return vals[0] * 2; }
ReturnType!bar bar(Parameters!bar vals) { return vals[0] * 2; }

all works fine!!

What am I doing wrong?

dmd 2.074
ldc 1.3.0 (main compiler, because can cross compile to arm)

Reply via email to