D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 6982 - immutability isn't respected on associative array assignment
Summary: immutability isn't respected on associative array assignment
Status: RESOLVED FIXED
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 normal
Assignee: No Owner
URL:
Keywords: accepts-invalid, pull
Depends on:
Blocks: 2573
  Show dependency treegraph
 
Reported: 2011-11-21 08:04 UTC by Trass3r
Modified: 2012-03-11 18:35 UTC (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Trass3r 2011-11-21 08:04:48 UTC
//struct Bla {}
alias int Bla;

import std.stdio;

void main()
{
		immutable(Bla[]) _a;
		writeln(_a.length); // prints 0
//		_a.length = 5; // Error: variable _a cannot modify immutable
		immutable(Bla)[] a = _a;
		a.length = 5;  // compiles, but:
		writeln(_a.length); // prints 0

		immutable(Bla[string]) _files;
		immutable(Bla)[string] files = _files;
}
Comment 1 timon.gehr 2011-11-21 08:30:21 UTC
That works as designed. I do not understand what you would expect it to do.

immutable(Bla[]) _a; // this is an array that cannot be changed
immutable(Bla)[] a; // this is an array whose elements cannot be changed

a = _a; // fine. a is now a slice to _a's data

a.length = 5; // reallocate storage for a.
assert(_a.length == 0); // length of _a does not change as it is a different variable
Comment 2 Trass3r 2011-11-21 08:43:41 UTC
Yeah, was a subtle error in reasoning.

But what about the assoc. array case?

        immutable(Bla[string]) _files = ["a":1, "b":2, "c":3];
        immutable(Bla)[string] files = _files; // works
        files["d"] = 5; // Error: files["d"] isn't mutable
        writeln(_files);
        writeln(files);

gdc rejects the assignment.
Comment 3 Trass3r 2011-11-21 08:51:18 UTC
Yep, it breaks immutability:

        immutable(Bla[string]) _files = ["a":1, "b":2, "c":3];
        immutable(Bla)[string] files = _files;
        files.remove ("a");
        writeln(_files);
        writeln(files);

prints:

["b":2, "c":3]
["b":2, "c":3]
Comment 4 timon.gehr 2011-11-21 12:06:10 UTC
Ok, I see. I change the title to reflect the actual bug.
Comment 5 Kenji Hara 2011-12-18 06:30:45 UTC
I think there are at least two issues.

void main()
{
    alias int Bla;
    immutable(Bla[string]) ifiles = ["a":1, "b":2, "c":3];
    immutable(Bla)[string] files = ifiles;  // (1)
    ifiles.remove ("a");                    // (2)
}

1. Implicitly conversion from immutable to mutable AA reference.
2. Call 'remove' from immutable AA reference.
Comment 6 bearophile_hugs 2011-12-18 07:39:16 UTC
A related problem (I think I have already put this in Bugzilla, but I don't remember the issue number):


void main() {
    int[char[]] aa; // line 2
    char[] a1 = "hello".dup;
    aa[a1] = 1; // line 4
}


It's stupid for D language to accept the line 2 and then refuse line 4 with:

test.d(4): Error: associative arrays can only be assigned values with immutable keys, not char[]

Line 2 too needs to become an error.

So a better error message is something like:

test.d(2): Error: built-in associative arrays accept only immutable keys, not char[]

Or alternatively:

test.d(2): Error: built-in associative arrays can be defined only with immutable keys, not char[]
Comment 8 github-bugzilla 2012-03-11 18:08:03 UTC
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/229a37a1ae0766a54cbe64fc3995847aa17f17fb
Merge pull request #799 from 9rnsr/fix6982

Issue 6982 - immutability isn't respected on associative array assignment