Thread overview
Troublemaker dmd 2.061 - Templates?
Jan 05, 2013
David
Jan 05, 2013
Ali Çehreli
Jan 05, 2013
David
Jan 05, 2013
David
Jan 07, 2013
nazriel
January 05, 2013
mixin template get_packets_mixin(alias Module) {
    template get_packets() {
        alias NoDuplicates!(get_packets_impl!(__traits(allMembers,
Module))) get_packets;
    }

    private template get_packets_impl(T...) {
        static if(T.length == 0) {
            alias TypeTuple!() get_packets_impl;
        } else static if(__traits(compiles, mixin(T[0]).id)) {
            pragma(msg, T);
            alias TypeTuple!(PacketTuple!(mixin(T[0]), mixin(T[0]).id),
get_packets_impl!(T[1..$])) get_packets_impl;
        } else {
            alias TypeTuple!(get_packets_impl!(T[1..$])) get_packets_impl;
        }
    }

    template PacketTuple(T, ubyte b) {
        alias T cls;
        alias b id;
    }

    pragma(msg, get_packets_impl!(__traits(allMembers, Module)));
    //pragma(msg, get_packets!());
}


This code worked fine from dmd 2.058 to 2.060 now it fails, haha you might think, gives you an error! no, it failed silently, and the pragma prints me "_error_", what a glorious message!, can anyone see if there is something wrong with this code? I don't see an error. Bug must be somewhere in get_packets_impl.

http://dpaste.dzfl.pl/d703d10e (code from above)
January 05, 2013
On 01/05/2013 08:52 AM, David wrote:

> http://dpaste.dzfl.pl/d703d10e (code from above)

That is equally incomplete. :) Could you please also provide surrounding code that would help us reproduce this issue? At the minimum, the import lines and a main() function will be helpful.

Thank you,
Ali

January 05, 2013
Am 05.01.2013 17:57, schrieb Ali Çehreli:
> On 01/05/2013 08:52 AM, David wrote:
> 
>> http://dpaste.dzfl.pl/d703d10e (code from above)
> 
> That is equally incomplete. :) Could you please also provide surrounding code that would help us reproduce this issue? At the minimum, the import lines and a main() function will be helpful.
> 
> Thank you,
> Ali
> 

16k codebase:

https://github.com/Dav1dde/BraLa/tree/master/brala/network/packets

util.d contains this code, server.d and client.d mix it in, it's used
like in parse_packet (util.d)
January 05, 2013
LOL
mixin template get_packets_mixin(alias Module) {
    template get_packets() {
        alias NoDuplicates!(get_packets_impl!(get_members!())) get_packets;
    }

    template get_members() {
        alias TypeTuple!(__traits(allMembers, Module)) get_members;
    }

    private template get_packets_impl(T...) {
        static if(__traits(compiles, mixin(T[0]).id)) {
//             pragma(msg, PacketTuple!(mixin(T[0]), mixin(T[0]).id));
//             pragma(msg, get_packets_impl!(T[1..$]));
            alias TypeTuple!(PacketTuple!(mixin(T[0]), mixin(T[0]).id),
get_packets_impl!(T[1..$])) get_packets_impl;
        } else {
//             pragma(msg, get_packets_impl!(T[1..$])); // <----------
            alias TypeTuple!(get_packets_impl!(T[1..$])) get_packets_impl;
        }
    }

    private template get_packets_impl() {
        alias TypeTuple!() get_packets_impl;
    }

    template PacketTuple(T, ubyte b) {
        alias T cls;
        alias b id;
    }

    auto parse_packet(ubyte id)(Stream s) {
        alias staticIndexOf!(id, staticMap!(extract_id, get_packets!()))
id_index;
        static if(id_index < 0) {
            static assert(false, "Invalid packet with id: " ~
toStringNow!id);
        } else {
            return get_packets!()[id_index].cls.recv(s);
        }
    }

    pragma(msg, get_packets_impl!(__traits(allMembers, Module)));
}

With this pragma: "pragma(msg, get_packets_impl!(T[1..$]));"
outcommented, I get _error_, but if I let it in, everything compiles.

I have no idea if I should laugh or cry.
January 07, 2013
On Saturday, 5 January 2013 at 18:45:26 UTC, David wrote:
> LOL
> mixin template get_packets_mixin(alias Module) {
>     template get_packets() {
>         alias NoDuplicates!(get_packets_impl!(get_members!())) get_packets;
>     }
>
>     template get_members() {
>         alias TypeTuple!(__traits(allMembers, Module)) get_members;
>     }
>
>     private template get_packets_impl(T...) {
>         static if(__traits(compiles, mixin(T[0]).id)) {
> //             pragma(msg, PacketTuple!(mixin(T[0]), mixin(T[0]).id));
> //             pragma(msg, get_packets_impl!(T[1..$]));
>             alias TypeTuple!(PacketTuple!(mixin(T[0]), mixin(T[0]).id),
> get_packets_impl!(T[1..$])) get_packets_impl;
>         } else {
> //             pragma(msg, get_packets_impl!(T[1..$])); // <----------
>             alias TypeTuple!(get_packets_impl!(T[1..$])) get_packets_impl;
>         }
>     }
>
>     private template get_packets_impl() {
>         alias TypeTuple!() get_packets_impl;
>     }
>
>     template PacketTuple(T, ubyte b) {
>         alias T cls;
>         alias b id;
>     }
>
>     auto parse_packet(ubyte id)(Stream s) {
>         alias staticIndexOf!(id, staticMap!(extract_id, get_packets!()))
> id_index;
>         static if(id_index < 0) {
>             static assert(false, "Invalid packet with id: " ~
> toStringNow!id);
>         } else {
>             return get_packets!()[id_index].cls.recv(s);
>         }
>     }
>
>     pragma(msg, get_packets_impl!(__traits(allMembers, Module)));
> }
>
> With this pragma: "pragma(msg, get_packets_impl!(T[1..$]));"
> outcommented, I get _error_, but if I let it in, everything compiles.
>
> I have no idea if I should laugh or cry.

Report a bug and mark it as regression if it is one.