[Issue 14090] New: [REG2.067a] Incorrect "recursive alias declaration"

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Sat Jan 31 08:47:12 PST 2015


https://issues.dlang.org/show_bug.cgi?id=14090

          Issue ID: 14090
           Summary: [REG2.067a] Incorrect "recursive alias declaration"
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Keywords: rejects-valid
          Severity: regression
          Priority: P1
         Component: DMD
          Assignee: nobody at puremagic.com
          Reporter: verylonglogin.reg at gmail.com

This code used to compile:
---
import std.algorithm: min, max;
import std.range: StoppingPolicy;
import std.traits;


template Template(alias Pred, int argumentsCount, EnumType = void)
    if(argumentsCount >= -1)
{
    static if(isSomeString!(typeof(Pred)))
    {
        template Template(Args...) if(argumentsCount == -1 || Args.length ==
argumentsCount)
        {
            static if(argumentsCount >= 1 && argumentsCount <= 2)
            {
                static if(__traits(compiles, { enum e = Args[0]; }))
                    enum a = Args[0];
                else static if(is(Args[0]))
                    alias T = Args[0];
                else
                    alias A = Args[0];

                static if(argumentsCount == 2)
                {
                    static if(__traits(compiles, { enum e = Args[1]; }))
                        enum b = Args[1];
                    else static if(is(Args[1]))
                        alias U = Args[1];
                    else
                        alias B = Args[1];
                }
            }

            static if(is(EnumType == void))
            {
                static if(__traits(compiles, { enum e = mixin(Pred); }))
                    enum Template = mixin(Pred);
                else
                    mixin(`alias Template = `~Pred~`;`);
            }
            else
            {
                enum EnumType Template = mixin(Pred);
            }
        }
    } else
        alias Template = Pred;
}

alias UnaryTemplate(alias Pred, EnumType = void) = Template!(Pred, 1,
EnumType);


alias GenericTuple(Args...) = Args;

template PackedGenericTuple(Args...)
{
    alias Tuple = Args;

    static if(isTypeTuple!Args)
        alias Types = Args;
    else static if(isExpressionTuple!Args)
        alias expressions = Args;

    enum length = Tuple.length;

    enum empty = !length;
}

template packedExpressionTuple(expr...) if(isExpressionTuple!expr)
{
    alias packedExpressionTuple = PackedGenericTuple!expr;
}


template RoundRobinTuple(packedTuples...)
{
    struct _Empty;
    enum pred(alias A) = !is(A == _Empty);
    alias ChainFunc(alias packedTuple) = packedTuple.Tuple;
    alias RoundRobinTuple = MapTuple!(ChainFunc,
ZipTuple!(StoppingPolicy.longest, GenericTuple!_Empty, packedTuples));
}

template ZipTuple(StoppingPolicy stoppingPolicy : StoppingPolicy.longest, alias
empty, packedTuples...)
{
    alias ZipTuple = ZipTupleImpl!(stoppingPolicy, PackedGenericTuple!empty,
packedTuples);
}

template ZipTuple(StoppingPolicy stoppingPolicy : StoppingPolicy.longest,
empty, packedTuples...)
{
    alias ZipTuple = ZipTupleImpl!(stoppingPolicy, PackedGenericTuple!empty,
packedTuples);
}

template ZipTuple(StoppingPolicy stoppingPolicy, packedTuples...)
    if(stoppingPolicy != StoppingPolicy.longest) // probably a compiler
@@@BUG@@@ workaround
{
    alias ZipTuple = ZipTupleImpl!(stoppingPolicy, PackedGenericTuple!void,
packedTuples);
}

template ZipTuple(packedTuples...)
{
    alias ZipTuple = ZipTuple!(StoppingPolicy.shortest, packedTuples);
}

private template ZipTupleImpl(StoppingPolicy stoppingPolicy, alias default_,
packedTuples...)
{
    alias lengths = MapTuple!(`A.length`, packedTuples);

    template Impl(size_t n, packedTuples...)
    {
        static if(n)
        {
            template tupleFrontOrDefault(alias packedTuple)
            {
                static if(!packedTuple.empty)
                    alias tupleFrontOrDefault = packedTuple.Tuple[0 .. 1];
                else
                    alias tupleFrontOrDefault = default_.Tuple;
            }
            alias Impl =
GenericTuple!(PackedGenericTuple!(MapTuple!(tupleFrontOrDefault,
packedTuples)),
                Impl!(n - 1, MapTuple!(`PackedGenericTuple!(A.Tuple[!A.empty ..
$])`, packedTuples)));
        }
        else
            alias Impl = GenericTuple!();
    }
    static if(packedTuples.length == 1 || stoppingPolicy ==
StoppingPolicy.requireSameLength)
        enum length = lengths[0];
    else
        enum length = GenericTuple!(min, max)
            [stoppingPolicy == StoppingPolicy.longest](lengths);

    alias ZipTupleImpl = Impl!(length, packedTuples);
}

template MapTuple(alias Func, A...)
{
    alias FuncTemplate = UnaryTemplate!Func;

    static if (A.length)
        alias MapTuple = GenericTuple!(FuncTemplate!(A[0]),
MapTuple!(FuncTemplate, A[1 .. $]));
    else
        alias MapTuple = GenericTuple!();
}


void main()
{
    alias roundRobin = RoundRobinTuple!(packedExpressionTuple!(1, 2, 3),
packedExpressionTuple!(10, 20, 30, 40));
}
---
main.d(60):        instantiated from here: isExpressionTuple!(_Empty, 40)
main.d(118):        instantiated from here: PackedGenericTuple!(_Empty, 40)
main.d(119):        instantiated from here: Impl!(1u, __T18PackedGenericTupleZ,
__T18PackedGenericTupleVii40Z)
main.d(119):        instantiated from here: Impl!(2u,
__T18PackedGenericTupleVii3Z, __T18PackedGenericTupleVii30Vii40Z)
main.d(119):        instantiated from here: Impl!(3u,
__T18PackedGenericTupleVii2Vii3Z, __T18PackedGenericTupleVii20Vii30Vii40Z)
main.d(130):        instantiated from here: Impl!(4u,
__T18PackedGenericTupleVii1Vii2Vii3Z,
__T18PackedGenericTupleVii10Vii20Vii30Vii40Z)
main.d(89):        instantiated from here: ZipTupleImpl!(cast(StoppingPolicy)1,
__T18PackedGenericTupleTS4main121__T15RoundRobinTupleS434main36__T18PackedGenericTupleVii1Vii2Vii3ZS514main44__T18PackedGenericTupleVii10Vii20Vii30Vii40ZZ6_EmptyZ,
__T18PackedGenericTupleVii1Vii2Vii3Z,
__T18PackedGenericTupleVii10Vii20Vii30Vii40Z)
main.d(79):        instantiated from here: ZipTuple!(cast(StoppingPolicy)1,
_Empty, __T18PackedGenericTupleVii1Vii2Vii3Z,
__T18PackedGenericTupleVii10Vii20Vii30Vii40Z)
main.d(146):        instantiated from here:
RoundRobinTuple!(__T18PackedGenericTupleVii1Vii2Vii3Z,
__T18PackedGenericTupleVii10Vii20Vii30Vii40Z)
---

Reduced from the same source (unstd.generictuple) as issue 13776.

--


More information about the Digitalmars-d-bugs mailing list