digitalmars.D.bugs - [Issue 15546] New: Spurious circular reference Error when using
- via Digitalmars-d-bugs (113/113) Jan 10 2016 https://issues.dlang.org/show_bug.cgi?id=15546
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 puremagic.com Reporter: puneet 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; } --
Jan 10 2016