Issue 1866 - Couple of reflection bugs (.stringof)
Summary: Couple of reflection bugs (.stringof)
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D1 (retired)
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2008-02-24 17:04 UTC by Jari-Matti Mäkelä
Modified: 2019-08-27 05:10 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Jari-Matti Mäkelä 2008-02-24 17:04:23 UTC
I marked these as bugs. Some of them are very painful for reflection. Others cannot be found from the specification. Yes I know there exists super funky __traits in d2, but why can't these work too? At least they need to be mentioned in the specs.


template tuple(T...) { alias T tuple; }

struct foo(A) {
  int a;
  tuple!(int,int) b;
  foo2 c;
}

enum foo2 : ubyte { A }

template ident(T) {
      pragma(msg, '"' ~ T.stringof ~ '"');
      alias T ident;
}

template print(T...) { alias int print; }

template print2(T, int n = 0) {
  static if (n < T.tupleof.length) {
    pragma(msg, T.tupleof[n].stringof);
    alias print2!(T, n+1) print2;
  } else
    alias int print2;
}

alias foo!(int) bar;


// BUG1:: inside ident(T) "foo!(int) " <- note the extra space

// BUG2:: .stringof returns "struct foo", this value is only returned on rare cases like this

pragma(msg, '"' ~ ident!(bar).stringof ~ '"');


// BUG3:: inside ident(T) "ubyte" <- not the enum name, just the base type (mentioned already elsewhere)

// BUG4:: .stringof returns "enum foo", this value is only returned on rare cases like this

pragma(msg, '"' ~ ident!(foo2).stringof ~ '"');

// returns "tuple(((foo!(int) ).a),((foo!(int) )._b_field_0),((foo!(int) )._b_field_1),((foo!(int) ).c),((foo!(int) ).d))"

// BUG1:: the extra space again after struct type

// BUG5:: extra parentheses around the struct type, second parentheses around every member

// BUG6:: the _membername_field_num isn't in lang specification (would be much easier if tuples could nest, sigh)

pragma(msg, '"' ~ bar.tupleof.stringof ~ '"');


// BUG7:: Error: tuple is not a valid template value argument (the tuple here is some unspecified type that cannot be expressed in D)

// pragma(msg, '"' ~ print!(bar.tupleof).stringof ~ '"');


// returns:
// (foo!(int) ).a
// (foo!(int) )._b_field_0
// (foo!(int) )._b_field_1
// ubyte

// BUG8:: .stringof returns again base type name, not the field name for enums unlike in .tupleof.stringof

alias print2!(bar) baz;
Comment 1 Jari-Matti Mäkelä 2008-02-24 17:37:56 UTC
Here's some test cases for the .tupleof. As you can see, there probably isn't any way to pass .tupleof to a template as a parameter - it feels like it is outside the D's type system. IMO it should return a tuple of compile time aliases.

template tuple(T...) { alias T tuple; }

struct foo { int a; }

template aaa(a) { alias int aaa; }
template bbb(alias a) { alias int bbb; }
//template ccc(foo.tupleof a) { alias int ccc; } // Error: foo.tupleof is used as a type
//template ddd(typeof(foo.tupleof) a) { alias int ddd; } // Error: arithmetic/string type expected for value-parameter, not (int)
//template eee(tuple!(foo.tupleof) a) { alias int eee; } // Error: tuple!(tuple(((foo ).a))) is used as a type
//template fff(tuple!(typeof(foo.tupleof)) a) { alias int fff; } // Error: arithmetic/string type expected for value-parameter, not (int)

//pragma(msg, aaa!(foo.tupleof).stringof); // template instance aaa!(tuple(((foo ).a))) does not match any template declaration
//pragma(msg, bbb!(foo.tupleof).stringof); // template instance bbb!(tuple(((foo ).a))) does not match any template declaration

//pragma(msg, ccc!(foo.tupleof).stringof); // the templates above failed
//pragma(msg, ddd!(foo.tupleof).stringof);
//pragma(msg, eee!(foo.tupleof).stringof);
//pragma(msg, fff!(foo.tupleof).stringof);
Comment 2 RazvanN 2019-08-27 05:10:45 UTC
I just ran the initial bug report and what I get is:

"foo!int"
"foo!int"
"foo2"
"foo2"
"tuple(a, __b_field_0, __b_field_1, c)"
a
__b_field_0
__b_field_1
c

Which is the correct output. Closing as WORKSFORME.