Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

Ticket #435 (closed defect: fixed)

Opened 14 years ago

Last modified 12 years ago

indexing a type item in a mixed tuple (tuple with types and values) returns a slice of that type item + pragma(msg, ...) doesn't work on type items

Reported by: manuel Assigned to: lindquist
Priority: major Milestone:
Component: frontend (both) Version: hg tip
Keywords: Cc:

Description

Note: I'm actually using version 0.9.2 and not hg tip, but 0.9.2 is not in the options list

There are various bugs with the "..." syntax for creating tuples, but I think they all root back to types being errously converted to singletons of itself when the number of arguments is >= 2.

// file tup_bug.d
template TupleBug(values...)
{
    alias values[0] v0;
    alias values[0][0][0][0][0] chain;

    pragma(msg, "values:    ", values);
    pragma(msg, "v0:        ", v0);
    pragma(msg, "values[0]: ", values[0]);
    pragma(msg, "chain:     ", chain);
}

pragma(msg, "-- TupleBug!(int):");
alias TupleBug!(int) _;

pragma(msg, "\n-- TupleBug!(int, \"foo\"):");
alias TupleBug!(int, "foo") _0;

void main() {}

Output of ldc 0.9.2 is

$ldc tup_bug.d
-- TupleBug!(int):
values:    (int)
v0:        int
values[0]: int
chain:     int[0LU][0LU][0LU][0LU]

-- TupleBug!(int, "foo"):
values:    tuple((int),"foo")
v0:        (int)
values[0]: int
chain:     (int)

Expected output for TupleBug?!(int, "foo"):

values:    tuple(int,"foo")
v0:        int
values[0]: int
chain:     int[0LU][0LU][0LU][0LU]

The output for TupleBug?!(int) is ok, but when the number of parameters is 2 or greater, then all types T in the parameter list are implicitly converted to a singleton tuple (T), as can be seen here in case of T=int. Even worse, you can not index the singleton tuple, it just returns a copy of itself, which is evident when looking at the output of chain.

In TupleBug?!(int), chain is a multidimensional array, which is correct. But in TupleBug?!(int, "foo"), the output of chain is just (int).

I also think the usage of tuple(...) and (...) in the output is inconsistend, it seems like tuple(...) is used for tuples of length >= 2 and (...) is used for singleton tuples only. I would use tuple(...) in both cases.

============================================================================

One really annoying consequence that's bugging me is that assigning names to template parameters via aliasing is not possible:

// file tup_bug_consequence.d
struct TypeAndName(args...)
{
    alias args[0] type; // "..." bug => type = (args[0]), not args[0]
    const char[] name = args[1];
}

template DeclVar(data)
{
    mixin("data.type "~data.name~";");
}

void main()
{
    mixin DeclVar!(TypeAndName!(int, "foo"));

    pragma(msg, "foo:          ", foo);
    pragma(msg, "typeof(foo): ", typeof(foo));
    foo = 3;
}

I expect this to define "int foo;" inside main, but due to the "..." bug described above, that doesn't work:

$ldc tup_bug_consequence.d
foo        : tuple(_foo_field_0)
typeof(foo): (int)
tup_bug_consequence.d(18): Error: foo is not an lvalue
tup_bug_consequence.d(18): Error: cannot implicitly convert expression (3) of type int to (int)
tup_bug_consequence.d(18): Error: cannot cast int to (int)

This TypeAndName? construct is really useful for parsing template arguments of the form (Type1, "name1", ..., TypeN, "nameN"), but as soon as you try to get an alias to one of the types, everything breaks. A workaround is to always work with the parameter tuple directly and don't alias its items, but then all your templates are reduced to magic tuple indexing code that no one can understand.

Attachments

patch_getTupleTypeItem.diff (0.9 kB) - added by manuel on 10/10/10 19:00:57.
Apply in directory ldc/dmd

Change History

10/09/10 19:13:39 changed by manuel

  • owner changed from ChristianK to lindquist.
  • component changed from unspecified to frontend (both).

Just built ldc from hg tip and verified the bug in ldc version

LLVM D Compiler rev. 1666:af31ff7a68c6 (2010-10-04 00:58 +0200) based on DMD v1.063 and llvm 2.7 (Sat Oct 2 23:03:20 2010)

Also verified the bug in dmd v2.049 and v1.056, so it's definitely a frontend bug.

10/10/10 19:00:57 changed by manuel

  • attachment patch_getTupleTypeItem.diff added.

Apply in directory ldc/dmd

10/10/10 19:03:38 changed by manuel

The patch_getTupleTypeItem.diff essentially fixes the bug, but in the pragma messages for tuples with mixed types and values, the types will still be printet in ( parantheses ). I also know the exact position where to fix that formatting bug and how it's caused, but I don't know which is a proper way to fix it.

10/10/10 21:09:54 changed by manuel

  • summary changed from Tuples created with "..." syntax of length >= 2 have the type arguments as singleton tuples [ (T) instead of T ] to indexing a type item in a mixed tuple (tuple with types and values) returns a slice of that type item + pragma(msg, ...) doesn't work on type items.

10/10/10 21:20:41 changed by manuel

Changed the summary to better reflect what's causing the bug. The bug was also reported on the dmd bugzilla as issue #3092. There I (user Manuel König) have also explained what causes the parantheses around int in the pragma(msg,...) outputs (it's only a formatting bug, no singleton tuples are created).

10/10/10 21:24:27 changed by manuel

Correction: For v0 and chain, singleton tuples are created, but that happens in the semantic phase of the aliasing. The parameters are passed in and processed correctly, just the pragma(msg, values) formatting is wrong.

06/24/12 08:58:37 changed by klickverbot

  • status changed from new to closed.
  • resolution set to fixed.

We inherited the fix from DMD since.

Copyright © 2008, LDC Development Team.