[Issue 15546] New: Spurious circular reference Error when using Mixin Template
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Sun Jan 10 10:40:23 PST 2016
https://issues.dlang.org/show_bug.cgi?id=15546
Issue ID: 15546
Summary: Spurious circular reference Error when using Mixin
Template
Product: D
Version: D2
Hardware: x86_64
OS: Linux
Status: NEW
Severity: normal
Priority: P1
Component: dmd
Assignee: nobody at puremagic.com
Reporter: puneet at coverify.org
I am getting a circular reference error when using a mixin template that
basically envelopes a string mixin. When the underlying string mixin is mixed
directly, no such error occurs.
I reduced the testcase, but it is still 90 lines long. I tried hard but could
not reduce further. I hope the code snippet is workable.
To replicate:
$ dmd -c test.d
test.d-mixin-55(56): Error: circular reference to 'test.R_inst._B_inst'
test.d(78): Error: mixin test.B.MixT!() error instantiating
test.d(66): Error: mixin test.A.MixT!() error instantiating
# string mixin compiles without errors
$ dmd -version=STRING -c test.d
// module test.d
public template Access(A...) {
static assert(A.length == 0);
enum string Access = "";
}
public template Accessor(T, string U="this", size_t I=0) {
static if(I == (__traits(derivedMembers, T).length)) {
enum string Accessor = "";
}
else {
enum string mem = __traits(derivedMembers, T)[I];
static if(mem == "this" || mem == "inst" || mem == "_inst") {
enum string Accessor = Accessor!(T, U, I+1);
}
else {
enum string Accessor =
"mixin(Accessor!(Access!(__traits(getAttributes, "
~ U ~ "." ~ mem ~ ")), \"" ~ mem ~ "\", \"" ~ U ~ "\"));
" ~ Accessor!(T, U, I+1);
}
}
}
public template Accessor(string A, string M, string U) {
static if(U == "_inst" || U == "inst") enum string SCOPE = "static";
enum string Accessor = A ~ " static final auto " ~ M[1..$] ~
"() {synchronized(" ~ U ~ ") return " ~ U ~ "." ~ M ~ ";}"
~ A ~ " static final void " ~ M[1..$] ~
"(typeof(" ~ U ~ "." ~ M ~ ") val) {synchronized(" ~ U ~ ") " ~
U ~ "." ~ M ~ " = val;}";
}
template Mix(T, U, size_t I=0) {
static if(I == (__traits(derivedMembers, T).length)) {
enum string Mix = "public static Single inst() {
return root.SingleRoot._" ~ U.stringof ~ "_inst;
}\n" ~ Accessor!(T, "inst");
}
else {
enum string mem = __traits(derivedMembers, T)[I];
static if(mem == "__ctor" || mem == "__dtor") {
enum string Mix = Mix!(T, U, I+1);
}
else {
enum string Mix = Mix!(T, U, I+1) ~
"static if(Access!(__traits(getAttributes, " ~
T.stringof ~ "." ~ mem ~ ")) != \"none\") {
static private ref " ~ " auto " ~ " " ~ mem ~ "() {
return inst." ~ mem ~ ";
}
}";
}
}
}
mixin template MixT() {
mixin(Mix!(Single, typeof(this)));
}
class A {
static class Single {
int _a;
}
version(STRING) {
mixin(Mix!(Single, A));
}
else {
mixin MixT;
}
}
class B
{
static class Single {
bool _b;
}
version(STRING) {
mixin(Mix!(Single, B));
}
else {
mixin MixT;
}
}
Root root;
class Root {
R_inst SingleRoot() { return new R_inst; }
}
class R_inst {
A.Single _A_inst;
B.Single _B_inst;
}
--
More information about the Digitalmars-d-bugs
mailing list