www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Error: Declaration is not yet implemented in CTFE

reply "bitwise" <nothx gmail.com> writes:
The docs for template mixins do show mixins inside functions, so 
is this a bug, or is there something else I'm doing wrong?

//**************************
module main;
import std.traits;

class ModInfo {

}

mixin template moduleInfo(alias MODULE) {
	static const(ModInfo) __module_info = new ModInfo;
}

const(ModInfo) getModuleInfo(alias mod)() {
	static if(__traits(hasMember, mod, "__module_info")) {
		return __traits(getMember, mod, "__module_info");
	} else {
		mixin moduleInfo!mod;      // ERROR [1]
		return __module_info;
	}
}

void main() {
	static const(ModInfo) info = getModuleInfo!(main);
}
//**************************

[1] main.d(17,3): Error: Declaration mixin moduleInfo!(main);
  is not yet implemented in CTFE
main.d(23,31):        called from here: getModuleInfo()
Nov 28 2014
next sibling parent reply Daniel Kozak via Digitalmars-d <digitalmars-d puremagic.com> writes:
Dne Fri, 28 Nov 2014 20:01:41 +0100 bitwise via Digitalmars-d  
<digitalmars-d puremagic.com> napsal(a):

 The docs for template mixins do show mixins inside functions, so is this  
 a bug, or is there something else I'm doing wrong?

 //**************************
 module main;
 import std.traits;

 class ModInfo {

 }

 mixin template moduleInfo(alias MODULE) {
 	static const(ModInfo) __module_info = new ModInfo;
 }

 const(ModInfo) getModuleInfo(alias mod)() {
 	static if(__traits(hasMember, mod, "__module_info")) {
 		return __traits(getMember, mod, "__module_info");
 	} else {
 		mixin moduleInfo!mod;      // ERROR [1]
 		return __module_info;
 	}
 }

 void main() {
 	static const(ModInfo) info = getModuleInfo!(main);
 }
 //**************************

 [1] main.d(17,3): Error: Declaration mixin moduleInfo!(main);
   is not yet implemented in CTFE
 main.d(23,31):        called from here: getModuleInfo()
module main; immutable class ModInfo { } static moduleInfo(alias MODULE)() { return new ModInfo(); } static getModuleInfo(alias mod)() { static if(__traits(hasMember, mod, "__module_info")) { return __traits(getMember, mod, "__module_info"); } else { return moduleInfo!mod; } } void main() { immutable info = getModuleInfo!(main); }
Nov 28 2014
parent reply "bitwise" <nothx gmail.com> writes:
On Friday, 28 November 2014 at 19:24:33 UTC, Daniel Kozak via 
Digitalmars-d wrote:
 Dne Fri, 28 Nov 2014 20:01:41 +0100 bitwise via Digitalmars-d 
 <digitalmars-d puremagic.com> napsal(a):

 The docs for template mixins do show mixins inside functions, 
 so is this a bug, or is there something else I'm doing wrong?

 //**************************
 module main;
 import std.traits;

 class ModInfo {

 }

 mixin template moduleInfo(alias MODULE) {
 	static const(ModInfo) __module_info = new ModInfo;
 }

 const(ModInfo) getModuleInfo(alias mod)() {
 	static if(__traits(hasMember, mod, "__module_info")) {
 		return __traits(getMember, mod, "__module_info");
 	} else {
 		mixin moduleInfo!mod;      // ERROR [1]
 		return __module_info;
 	}
 }

 void main() {
 	static const(ModInfo) info = getModuleInfo!(main);
 }
 //**************************

 [1] main.d(17,3): Error: Declaration mixin moduleInfo!(main);
  is not yet implemented in CTFE
 main.d(23,31):        called from here: getModuleInfo()
module main; immutable class ModInfo { } static moduleInfo(alias MODULE)() { return new ModInfo(); } static getModuleInfo(alias mod)() { static if(__traits(hasMember, mod, "__module_info")) { return __traits(getMember, mod, "__module_info"); } else { return moduleInfo!mod; } } void main() { immutable info = getModuleInfo!(main); }
Thanks, but this still doesn't fix my problem. The idea is that getModuleInfo should return the same static copy of ModInfo at each call to avoid duplication. ModInfo is a recursive reflection of an entire module, so it could be huge. My goal is that someone could create a global (ModInfo __module_info) object inside their own module through a mixin template, which would allow reflection of private members in that module. If getModuleInfo() was called for a module that was missing __ module_info, a static copy would be created inside getModuleInfo(). This would be the case if someone wanted to reflect a static library that they themselves did not compile.
Nov 28 2014
parent reply Daniel Kozak via Digitalmars-d <digitalmars-d puremagic.com> writes:
Dne Fri, 28 Nov 2014 22:55:27 +0100 bitwise via Digitalmars-d  
<digitalmars-d puremagic.com> napsal(a):

 On Friday, 28 November 2014 at 19:24:33 UTC, Daniel Kozak via  
 Digitalmars-d wrote:
 Dne Fri, 28 Nov 2014 20:01:41 +0100 bitwise via Digitalmars-d  
 <digitalmars-d puremagic.com> napsal(a):

 The docs for template mixins do show mixins inside functions, so is  
 this a bug, or is there something else I'm doing wrong?

 //**************************
 module main;
 import std.traits;

 class ModInfo {

 }

 mixin template moduleInfo(alias MODULE) {
 	static const(ModInfo) __module_info = new ModInfo;
 }

 const(ModInfo) getModuleInfo(alias mod)() {
 	static if(__traits(hasMember, mod, "__module_info")) {
 		return __traits(getMember, mod, "__module_info");
 	} else {
 		mixin moduleInfo!mod;      // ERROR [1]
 		return __module_info;
 	}
 }

 void main() {
 	static const(ModInfo) info = getModuleInfo!(main);
 }
 //**************************

 [1] main.d(17,3): Error: Declaration mixin moduleInfo!(main);
  is not yet implemented in CTFE
 main.d(23,31):        called from here: getModuleInfo()
module main; immutable class ModInfo { } static moduleInfo(alias MODULE)() { return new ModInfo(); } static getModuleInfo(alias mod)() { static if(__traits(hasMember, mod, "__module_info")) { return __traits(getMember, mod, "__module_info"); } else { return moduleInfo!mod; } } void main() { immutable info = getModuleInfo!(main); }
Thanks, but this still doesn't fix my problem. The idea is that getModuleInfo should return the same static copy of ModInfo at each call to avoid duplication. ModInfo is a recursive reflection of an entire module, so it could be huge.
Yes this will
Nov 28 2014
parent reply "bitwise" <nothx gmail.com> writes:
 Yes this will
I think I may not have explained myself correctly, which is a mistake I often make in an effort to simplify the question =/ but, the assertion in the code below fails: immutable class ModInfo {} static moduleInfo(alias MODULE)() { return new ModInfo(); } static getModuleInfo(alias mod)() { static if(__traits(hasMember, mod, "__module_info")) { return __traits(getMember, mod, "__module_info"); } else { return moduleInfo!mod; } } void main() { immutable info = getModuleInfo!(main); immutable info2 = getModuleInfo!(main); assert(info == info2); // fail }
 The 'unique ModInfo per module' is done by the templated 
 variable 1.
I didn't eventually use a variable template, but this did prompt me to give the templates/mixins section another read ;) My design had several requirements which were very not easy to satisfy all at once, but I think I have finally found something that works. I needed the module info to be generated once at compile time. Also, it needed to be available both at compile time, and runtime, which means I had to be able to reference it directly in both cases. But, at the same time, the caller had to have the option of placing the reflection implementation inside the actual module itself so that it could access to all the module's private symbols. So after 2 full days chasing errors and circular dependancies, the following seems to work: // contains all reflection template subclasses used at compile time mixin template _implementations(alias MODULE) { class ModuleDeclImpl(alias T) : ModuleDecl { static this() { _allModules[ T.stringof[7..$] ] = getModuleInfo!T; } } // ... } // create reflection info template moduleInfo(alias MODULE) { mixin _implementations!(MODULE); const(ModuleDecl) moduleInfo = new ModuleDeclImpl!MODULE; } // generate reflection for a module inside itself mixin template reflection() { alias moduleAlias!(.stringof[7..$]) thisModule; static const(ModuleDecl) __module_info = moduleInfo!thisModule; } // generate reflection for a module from inside a different module mixin template reflection(alias MODULE) { static assert(!__traits(hasMember, MODULE, "__module_info"), "Reflection information already exists for " ~ MODULE.stringof); mixin("static const(ModuleDecl) __" ~ MODULE.stringof[7..$] ~ "_info = moduleInfo!MODULE;"); } // get reflection info at compile time const(ModuleDecl) getModuleInfo(alias MODULE)() { static if(__traits(hasMember, MODULE, "__module_info")) { return __traits(getMember, MODULE, "__module_info"); } else { static const(ModuleDecl) __module_info = moduleInfo!MODULE; return __module_info; } } // get reflection info at runtime extern(C) export const(ModuleDecl) getModuleInfo(string name) { return ModuleDecl.allModules[name]; } void main() { static m = getModuleInfo!(test); static m2 = getModuleInfo!(test); static m3 = getModuleInfo!(test); assert(m == m2); // PASS assert(m == m3); // PASS }
Nov 29 2014
parent "bitwise" <nothx gmail.com> writes:
 void main() {
 	static m = getModuleInfo!(test);
 	static m2 = getModuleInfo!(test);
 	static m3 = getModuleInfo!(test);

 	assert(m == m2); // PASS
 	assert(m == m3); // PASS
 }
correction: static m = getModuleInfo!(test); static m2 = getModuleInfo!(test); auto m3 = getModuleInfo("test"); // runtime retrieval assert(m == m2); // PASS assert(m == m3); // PASS
Nov 29 2014
prev sibling parent "Daniel Murphy" <yebbliesnospam gmail.com> writes:
"bitwise"  wrote in message news:bzzwikiplqydlzmphllp forum.dlang.org...

 The docs for template mixins do show mixins inside functions, so is this a 
 bug, or is there something else I'm doing wrong?
Both a bug, and you're doing something wrong. CTFE should be giving you a 'cannot read static variable at compile time' error. Try this: import std.traits; class ModInfo { } const(ModInfo) moduleInfo(alias MODULE) = new ModInfo(); // 1 const(ModInfo) getModuleInfo(alias mod)() { static if(__traits(hasMember, mod, "__module_info")) { return __traits(getMember, mod, "__module_info"); } else { return moduleInfo!mod; } } void main() { static const(ModInfo) info = getModuleInfo!(main); } The 'unique ModInfo per module' is done by the templated variable 1.
Nov 28 2014