www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Constancy lost when compiling template mixin

The following program won't compile (and I think it should)

    void main()
    {
        A!(float) a;
    }

    struct A(V:V)
    {
        pragma(msg,"Compiling A!(" ~ V.stringof ~ ")");
        alias typeof(V) M;
        pragma(msg,"type of M is " ~ M.stringof);

        V[] a;

        template B(U:U)
        {
            pragma(msg,"Compiling A.B!(" ~ U.stringof ~ ")");
            U* p() { return a.ptr; }
            pragma(msg,"Compiled A.B!(" ~ U.stringof ~ ")");
        }

        const
        {
            pragma(msg,"About to compile A.B!(const(" ~ M.stringof ~ "))");
            mixin B!(const(M));
            pragma(msg,"Finished compiling A.B!(const(" ~ M.stringof ~ "))");
        }

        pragma(msg,"Compiled A!(" ~V.stringof ~ ")");
    }


During compilation, the following gets printed out:

    Compiling A!(float)
    type of M is float
    About to compile A.B!(const(float))
    Compiling A.B!(float)
    Compiled A.B!(float)
    Finished compiling A.B!(const(float))
    Compiled A!(float)
    test.d(17): Error: cannot implicitly convert expression
(cast(const(float)*)(this.a)) of type const(float)* to float*
    test.d(3): template instance test.A!(float) error instantiating


As you can see, the pragma within the const block spits out "About to
compile A.B!(const(float))". However, when A.B is mixed in, the pragma
at the start of A.B prints "Compiling A.B!(float)" - NOT (as one might
expect) "Compiling A.B!(const(float))".

The constancy of "const(float)" has been lost! U is now just "float",
instead of "const(float)".

In consequence, the return type of p() is wrong, and the "cannot
implicitly convert" error results.

The REAL error, however, is that U should be "const(float)", not
"float". What happened? Is this a bug, or am I doing something wrong?
Dec 11 2007