www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - internal compiler error with immutable

reply "Danny" <danny.milo+a gmail.com> writes:
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).
Feb 07 2015
next sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Sat, Feb 07, 2015 at 02:35:13PM +0000, Danny via Digitalmars-d-learn wrote:
[...]
 ------------------------------------<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>-------------------------
[...] Please file a bug at http://issues.dlang.org/. Compiler internal errors are *always* bugs that need to be fixed. Thanks! T -- English is useful because it is a mess. Since English is a mess, it maps well onto the problem space, which is also a mess, which we call reality. Similarly, Perl was designed to be a mess, though in the nicest of all possible ways. -- Larry Wall
Feb 07 2015
next sibling parent "Danny" <danny.milo+a gmail.com> writes:
Hi,

I've filed it with gdcproject.org before reading your reply. Will 
it be forwarded to issues.dlang.org or should I file it there as 
well?

Also, it seems there's a new DMD release underway right now, does 
it still happen with that? (I tried but can't get it to build - 
doesn't seem to support ARMHF target)
Feb 07 2015
prev sibling parent ketmar <ketmar ketmar.no-ip.org> writes:
On Sat, 07 Feb 2015 09:23:42 -0800, H. S. Teoh via Digitalmars-d-learn
wrote:

 On Sat, Feb 07, 2015 at 02:35:13PM +0000, Danny via Digitalmars-d-learn
 wrote:
 [...]
 ------------------------------------<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>-------------------------
[...] =20 Please file a bug at http://issues.dlang.org/. Compiler internal errors are *always* bugs that need to be fixed. Thanks!
this is both non-DMD bug, and nonexistent-in-new-gdc bug.=
Feb 08 2015
prev sibling next sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/07/2015 06:35 AM, Danny wrote:

 I'm trying to use immutable class instances and that seems to be really
 difficult.
You are not alone. :) Just some reminders: - immutable is a requirement that may not be usable with every type. - immutable string foo() {} is a member function that works on immutable objects. For that reason, that 'immutable' is recommended to appear after the parameter list: string foo() immutable {}
 For example, with the following program I get an internal compiler error:
It generates regular compilation errors with dmd git head.
      override immutable string toString() {
I received the following error for the toString() function above as there is no 'Object.toString immutable' to override: Error: function deneme.Attrsp.toString does not override any function, did you mean to override 'object.Object.toString'?
          for(i = 0U; i < MAX_COMPRESSED_ATTRS; ++i) {
              if(codes[i] is null) {
I received the followin compilation error for the line above: Error: non-shared inout method std.typecons.Rebindable!(immutable(Attrsp)).Rebindable.RebindableCommon (immutable(Attrsp), Attrsp, Rebindable!(immutable(Attrsp))).get is not callable using a shared mutable object
 I'm not even trying to modify the contents of the instance, I'm
 just trying to assign another one to the array slot
That would be a violation of immutable, no?
 (actually not even another one - it was null before).
The compiler does not keep track of variables to see that it is null. Since immutable (and const) are transitive, it does not allow rebinding a class reference. Ali
Feb 08 2015
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/07/2015 06:35 AM, Danny wrote:

 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).
The following is based on my understanding of that description: import std.conv; import std.concurrency; import std.stdio; class C { int value; // Constructor for immutable(C) objects this (int value) immutable { this.value = value; } } // Stores commonly used C objects and allows access to them by // ubyte indexes class CommonlyUsedCs { immutable(C)[] cs; // This add() works on 'shared' CommonlyUsedCs objects ubyte add(immutable(C) c) shared { ubyte index; synchronized { index = cs.length.to!ubyte; cs ~= c; } return index; } immutable(C) get(ubyte index) const shared { return cs[index]; } } void main() { auto cucs = new shared(CommonlyUsedCs)(); // Populate the Cs foreach (ubyte i; 0 .. 10) { if (i % 2) { cucs.add(new immutable(C)(i)); } } // Start a thread and tell it what index its C is at spawn(&user, cucs, ubyte(3)); } void user(shared(CommonlyUsedCs) cucs, ubyte index) { writefln("My C has value %s", cucs.get(index).value); } Ali
Feb 08 2015
parent reply "Danny" <danny.milo+a gmail.com> writes:
Hi Ketmar,
Hi Ali,

thank you!

On Sunday, 8 February 2015 at 09:42:14 UTC, Ali Çehreli wrote:
     spawn(&user, cucs, ubyte(3));
^^^^^^^^^^^^^^^^^^^^^^^^^to! Other than that, it works. (The Attributes are basically literal constants but the library cannot know which are used in a given program - but probably not more than 20 or so are used realistically - it would be a UI design faux pas for content to be - like XP start menu - in hundreds of different yellowish greenish colors) Unfortunately, I can't seem to get opEquals to work with immutable (or const, for that matter) either. (does compile, though) The obvious bool opEquals(immutable(C) b) immutable { return value == b.value; } doesn't work. Probably have to override the one from Object ? Even though I don't really use polymorphism here. override bool opEquals(Object b) immutable { return value == (cast(immutable(C)) b).value; } Nope. Doesn't work (or compile) either. As a test, I added foreach (ubyte i; 0 .. 10) { if (i % 2) { cucs.add(new immutable(C)(i)); assert(new immutable(C)(i) == new immutable(C)(i)); // this } } to your program but the assertion fails after the changes (if it even compiles). Hmm, maybe I should just store immutable struct C pointers? Yep, that works, although then I have to compare for equality by *a == *b... oh well, I use opEquals comparison only internally after all.
Feb 08 2015
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/08/2015 05:21 AM, Danny wrote:

 The obvious
      bool opEquals(immutable(C) b) immutable {
          return value == b.value;
      }
 doesn't work. Probably have to override the one from Object ? Even
 though I don't really use polymorphism here.

      override bool opEquals(Object b) immutable {
          return value == (cast(immutable(C)) b).value;
      }

 Nope. Doesn't work (or compile) either.
Yes, opEquals for classes has a particular syntax: http://ddili.org/ders/d.en/object.html#ix_object.opEquals Remember that 'const' binds to immutable as well. The following works with at least git head: override bool opEquals(Object b) const { auto rhs = cast(C)b; return rhs && (value == rhs.value); } Ali
Feb 09 2015