Thread overview
[Issue 21891] Cannot alias every kind that can be passed via variadic templates
May 03
https://issues.dlang.org/show_bug.cgi?id=21891

hsteoh@quickfur.ath.cx changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hsteoh@quickfur.ath.cx

--- Comment #1 from hsteoh@quickfur.ath.cx ---
This makes me wonder why alias parameters were introduced in the first place. Phobos makes extensive use of alias parameters for binding to lambdas, for example, so it appears that it was a deliberate decision to distinguish between unmarked template parameters receiving types vs alias parameters receiving things that might not be types.  But yeah, this subtle and mostly-arbitrary distinction is the source of a number of weird corner cases and inhomogeneities in Phobos and also in the language in general.

My inclination is to get rid of this arbitrary distinction so that the language has less special cases.

--
May 03
https://issues.dlang.org/show_bug.cgi?id=21891

Paul Backus <snarwin+bugzilla@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |snarwin+bugzilla@gmail.com

--- Comment #2 from Paul Backus <snarwin+bugzilla@gmail.com> ---
(In reply to Andrei Alexandrescu from comment #0)
> So in fact 1 is bindable to an alias but somehow not in all contexts!

Specifically: an expression can bind to a template alias parameter, but is not allowed on the right-hand side of an alias declaration.

The reason `alias Y = X;` works but `alias Y = X[0];` doesn't is that `X` by itself on the right-hand side is parsed as a symbol, not an expression. The variadic parameter is a distraction.

--
May 04
https://issues.dlang.org/show_bug.cgi?id=21891

--- Comment #3 from Andrei Alexandrescu <andrei@erdani.com> ---
(In reply to Paul Backus from comment #2)
> (In reply to Andrei Alexandrescu from comment #0)
> > So in fact 1 is bindable to an alias but somehow not in all contexts!
> 
> Specifically: an expression can bind to a template alias parameter, but is not allowed on the right-hand side of an alias declaration.
> 
> The reason `alias Y = X;` works but `alias Y = X[0];` doesn't is that `X` by itself on the right-hand side is parsed as a symbol, not an expression. The variadic parameter is a distraction.

Very interesting, thank you!

--
May 04
https://issues.dlang.org/show_bug.cgi?id=21891

--- Comment #4 from Andrei Alexandrescu <andrei@erdani.com> ---
(In reply to Paul Backus from comment #2)
> (In reply to Andrei Alexandrescu from comment #0)
> > So in fact 1 is bindable to an alias but somehow not in all contexts!
> 
> Specifically: an expression can bind to a template alias parameter, but is not allowed on the right-hand side of an alias declaration.
> 
> The reason `alias Y = X;` works but `alias Y = X[0];` doesn't is that `X` by itself on the right-hand side is parsed as a symbol, not an expression. The variadic parameter is a distraction.

Hm... how does this fit then? Just found it in core.internal.traits:

template maxAlignment(U...)
{
    static if (U.length == 0)
        static assert(0);
    else static if (U.length == 1)
        enum maxAlignment = U[0].alignof;
    else static if (U.length == 2)
        enum maxAlignment = U[0].alignof > U[1].alignof ? U[0].alignof :
U[1].alignof;
    else
    {
        enum a = maxAlignment!(U[0 .. ($+1)/2]);
        enum b = maxAlignment!(U[($+1)/2 .. $]);
        enum maxAlignment = a > b ? a : b;
    }
}

template classInstanceAlignment(T)
if (is(T == class))
{
    alias classInstanceAlignment = maxAlignment!(void*, typeof(T.tupleof));
}


Does that work because there's a template instantiation on the right-hand side?

--
May 04
https://issues.dlang.org/show_bug.cgi?id=21891

--- Comment #5 from Paul Backus <snarwin+bugzilla@gmail.com> ---
(In reply to Andrei Alexandrescu from comment #4)
> template classInstanceAlignment(T)
> if (is(T == class))
> {
>     alias classInstanceAlignment = maxAlignment!(void*, typeof(T.tupleof));
> }
> 
> 
> Does that work because there's a template instantiation on the right-hand side?

Yes. It's the same reason that `Alias!(expr)` sometimes works when `expr`
doesn't.

--