Thread overview
[Issue 9828] New: Inconsistent lowering of 1-element tuple to its element
Mar 29, 2013
Andrej Mitrovic
Mar 29, 2013
Andrej Mitrovic
Jul 24, 2013
Kenji Hara
March 29, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9828

           Summary: Inconsistent lowering of 1-element tuple to its
                    element
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: druntime
        AssignedTo: nobody@puremagic.com
        ReportedBy: andrej.mitrovich@gmail.com


--- Comment #0 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-03-29 08:54:26 PDT ---
template tuple(T...) { alias tuple = T; }

template get(alias sym)
{
    alias get = sym;
}

void main()
{
    alias tuple!(int, float) IntFloat;
    // alias a = get!IntFloat;  // does not match, OK

    alias tuple!(int) Int;
    // alias b = get!Int;  // does not match, OK

    alias tuple!("foo", "bar") FooBar;
    // alias c = get!FooBar;  // does not match, OK

    alias tuple!("foo") Foo;
    alias d = get!Foo;  // works, ??

    if (d == "foo") { }  // works
    if (Foo == "foo") { }  // does not work
}

It's really strange that a 1-element tuple seems to be implicitly convertible to its element type when it's passed by alias, yet we cannot directly compare a 1-element tuple against another element of the same type.

Either it should be consistently allowed to use a 1-element tuple as if it were the element itself, or it should never be implicitly convertible to the element type. It should be consistent.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
March 29, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9828



--- Comment #1 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-03-29 08:59:30 PDT ---
Here's an example of why it would be useful if it's consistently allowed:

import std.typetuple;

template getTypes(T...)
{
    alias getTypes = T;
}

void test(T)(T t)
{
    alias attributes = getTypes!(__traits(getAttributes, T));

    // NG: Even if tuple length is 1
    // static if (attributes == "S1") { }

    // NG: '(string)' and '(string)' (why are they not comparable?)
    // static if (attributes == TypeTuple!("S1")) { }

    // Note: .length check is necessary, otherwise out of bounds errors occur
    static if (attributes.length && attributes[0] == "S1")
    {
        pragma(msg, T);
    }
}

void main()
{
    @("S1") static struct S1 { }
    static struct S2 { }
    test(S1());
    test(S2());
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 24, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=9828



--- Comment #2 from Kenji Hara <k.hara.pg@gmail.com> 2013-07-23 18:39:52 PDT ---
(In reply to comment #0)
>     alias tuple!("foo") Foo;
>     alias d = get!Foo;  // works, ??

Here's no inconsistency. If you give a tuple as template argument, it would be
automatically expanded to its elements.
And if the tuple contains just one symbol element, the template argument would
match to alias version.

>     if (d == "foo") { }  // works
>     if (Foo == "foo") { }  // does not work

OTOH, currently one-element tuple is not automatically expanded to the element
itself on the each side of binary operator.
I'm not sure this is well designed, but I think that holding the distinction of
them would be valuable than mixing them.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------