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).

Reply via email to