Error: Declaration is not yet implemented in CTFE

bitwise via Digitalmars-d digitalmars-d at puremagic.com
Sat Nov 29 10:28:56 PST 2014


>> 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
}



More information about the Digitalmars-d mailing list