internal compiler error with immutable

Danny via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Feb 7 06:35:13 PST 2015


Hi,

I'm trying to use immutable class instances and that seems to be 
really difficult.

For example, with the following program I get an internal 
compiler error:

------------------------------------<cut>-------------------------
import std.outbuffer : OutBuffer;
import std.typecons : Rebindable;

enum Attrkey : ubyte {
	Fgcolor,
	Bgcolor,
}

enum MAX_COMPRESSED_ATTRS = 128U;
alias Codes = Rebindable!(Attrs)[MAX_COMPRESSED_ATTRS];
static shared Codes codes;
private class Attrsp {
	immutable(Attrsp) next;
	Attrkey key;
	ubyte value;
	private this(Attrkey key, ubyte value, immutable(Attrsp) next) {
		this.next = next;
		this.key = key;
		this.value = value;
	}
	// FIXME allow comparing the entire chain for equality.
	private immutable void print(OutBuffer destination /* 
destination */) {
		destination.write("Attrs(");
		destination.write(cast(ubyte) key); // FIXME .toString()
		destination.write(", ");
		destination.write(value);
		destination.write(", \n");
		if(this.next is null)
			destination.write("null");
		else
			next.print(destination);
		destination.write(")");
	}
	override immutable string toString() {
		auto destination = new OutBuffer();
		print(destination);
		return destination.toString();
	}
	// TODO add newless static opCall which also does compression?
	/*doesn't work static immutable immutable(Attrsp) opCall(Attrkey 
key, ubyte value, immutable(Attrsp) next) {
		return new immutable Attrsp(key, value, next);
	}*/
	alias Code = ubyte;
	/* Compresses the given attributes into 1 Byte, if possible.
	   Returns MAX_COMPRESSED if it's not possible. */
	static Code compress(immutable(Attrs) node) { // FIXME make 
thread safe
		ubyte i;
		for(i = 0U; i < MAX_COMPRESSED_ATTRS; ++i) {
			if(codes[i] is null) {
				codes[i] = node;
				return i;
			} else if(codes[i] == node)
				return i;
		}
		return i; // tell that it didn't work.
	}
	static immutable(Attrs) uncompress(Code value) {
		assert(value >= 0U && value < MAX_COMPRESSED_ATTRS);
		return codes[value];
	}
}
alias Attrs = immutable(Attrsp);
------------------------------------<cut>-------------------------
gdc A.d
cc1d: ../../src/gcc/d/dfrontend/statement.c:293: 
ErrorStatement::ErrorStatement(): Assertion `global.gaggedErrors 
|| global.errors' failed.
cc1d: internal compiler error: Aborted
Please submit a full bug report,
with preprocessed source if appropriate.
See <file:///usr/share/doc/gcc-4.9/README.Bugs> for instructions.
gdc (Debian 4.9.1-19) 4.9.1
------------------------------------<cut>-------------------------

What I'm trying to do is save space by putting often-used Attrs 
into an array and just compressing references to those into 1 
Byte in the other data structures where it's used (these other 
data structures are not thread-local). Why do I need Rebindable 
to begin with? I'm not even trying to modify the contents of the 
instance, I'm just trying to assign another one to the array slot 
(actually not even another one - it was null before).


More information about the Digitalmars-d-learn mailing list