Thread overview
[Issue 21891] Cannot alias every kind that can be passed via variadic templates
May 03, 2021
Paul Backus
May 04, 2021
Paul Backus
Dec 17, 2022
Iain Buclaw
May 03, 2021
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, 2021
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, 2021
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, 2021
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, 2021
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.

--
December 17, 2022
https://issues.dlang.org/show_bug.cgi?id=21891

Iain Buclaw <ibuclaw@gdcproject.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P1                          |P2

--