[Issue 6056] New: Type lookup problem in string mixins

d-bugmail at puremagic.com d-bugmail at puremagic.com
Wed May 25 09:26:21 PDT 2011


http://d.puremagic.com/issues/show_bug.cgi?id=6056

           Summary: Type lookup problem in string mixins
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Mac OS X
            Status: NEW
          Severity: major
          Priority: P2
         Component: DMD
        AssignedTo: nobody at puremagic.com
        ReportedBy: code at klickverbot.at


--- Comment #0 from klickverbot <code at klickverbot.at> 2011-05-25 09:22:04 PDT ---
Apologies for the vague title, but I'm not quite sure how to appropriately
describe this issue. Consider the following snippet:

---
import std.traits : ParameterTypeTuple;

interface Bar {
  int a(int t);
  int b(short t);
}

template Foo(string name) {
  mixin(
    "alias ParameterTypeTuple!(Bar." ~ name ~ ")[0] Type;\n" ~
    "alias const(Type)* PointerType;"
  );
  mixin("alias const(ParameterTypeTuple!(Bar." ~ name ~ ")[0])*
PointerTypeDirect;");
  pragma(msg, name, ": ", Type, ", ", PointerType, ", ", PointerTypeDirect);
}

// The second instantiation always prints the same for PointerTypeDirect as
// the first, try swapping them.
alias Foo!("a") FooA;
alias Foo!("b") FooB;
---

DMD from current Git master (ef2b5aa) prints:
---
a: int, const(int)*, int*
b: short, const(short)*, int* 
---

Note that PointerTypeDirect is the same type on the second instantiation, while
the version using an intermediary alias works fine. If the two instantiation
lines are swapped, the output is as follows:
---
b: short, const(short)*, short*
a: int, const(int)*, short*
---

The two step version still works fine, whereas the direct version now has
short* in both cases.


You might have noticed that it would be enough to use a string mixin expression
for the ParameterTypeTuple argument instead of mixing in the whole declaration.
If one replaces Foo by this:
---
template Foo(string name) {
  alias const(ParameterTypeTuple!(mixin("Bar." ~ name))[0])* PointerTypeDirect;
  pragma(msg, name, ": ", PointerTypeDirect);
}
---

The output is:
---
a: int*
b: short*
---

The const seems to be missing, but otherwise it seems to work – but if the
original line is added in again:
---
template Foo(string name) {
  mixin("alias const(ParameterTypeTuple!(Bar." ~ name ~ ")[0])* NotRelevant;");
  alias const(ParameterTypeTuple!(mixin("Bar." ~ name))[0])* PointerTypeDirect;
  pragma(msg, name, ": ", PointerTypeDirect);
}
---

The output again becomes:
---
a: int*
b: int*
---


If the original code is changed to declare a normal, non-const pointer, it
works as expected as well:
---
template Foo(string name) {
  mixin("alias ParameterTypeTuple!(Bar." ~ name ~ ")[0]* PointerTypeDirect;");
  pragma(msg, name, ": ", PointerTypeDirect);
}
---

Correctly results in:
---
a: int*
b: short*
---

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


More information about the Digitalmars-d-bugs mailing list