Bug 6906 – Cannot assign value into associative array if contains opAssign

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-11-07T12:24:00Z
Last change time
2013-09-07T10:01:04Z
Keywords
rejects-valid
Assigned to
nobody
Creator
Jesse.K.Phillips+D

Comments

Comment #0 by Jesse.K.Phillips+D — 2011-11-07T12:24:00Z
This code fails to compile because the struct S implement opAssign and the compiler tries using it rather than the associative arrays insert. void main() { S[string] ss; S s; ss["hello"] = s; } struct S { void opAssign(int i) { } } test.d(6): Error: function test.S.opAssign (int i) is not callable using argument types (S) test.d(6): Error: cannot implicitly convert expression (s) of type S to int test.d(6): Error: function test.S.opAssign (int i) is not callable using argument types (S) test.d(6): Error: cannot implicitly convert expression (s) of type S to int PS C:\Documents and Settings\jphillips\src\Juno> dmd test.d test.d(5): Error: function test.S.opAssign (int i) is not callable using argument types (S) test.d(5): Error: cannot implicitly convert expression (s) of type S to int test.d(5): Error: function test.S.opAssign (int i) is not callable using argument types (S) test.d(5): Error: cannot implicitly convert expression (s) of type S to int
Comment #1 by clugdbug — 2011-11-07T23:07:16Z
I don't think this is a bug. I think the behaviour is intuitive. ss["hello"] = s; looks like an assignment, and it currently behaves like one. This code doesn't compile, either: S[2] ss; S s; ss[0] = s; As you've defined it, S cannot participate in any assignment of any kind. You can't even write: S s; S t; t = s;
Comment #2 by Jesse.K.Phillips+D — 2011-11-08T07:16:04Z
Can I then say you aren't able to define opAssign for a struct and have it work for associative arrays: void main() { S[string] ss; S s; ss["hello"] = s; } struct S { void opAssign(int i) { } void opAssign(S s) { this = s; } } /tmp$ ./test Segmentation fault
Comment #3 by clugdbug — 2011-11-08T22:59:29Z
(In reply to comment #2) > Can I then say you aren't able to define opAssign for a struct and have it work > for associative arrays: > > /tmp$ ./test > Segmentation fault That's definitely a problem, but I don't think it has anything to do with AAs. This also creates a stack overflow: void main() { S s; S t; t = s; } struct S { void opAssign(S s) { this = s; } } Obviously it's changing 'this = XXX' into 'this.opAssign(XXX)'.
Comment #4 by k.hara.pg — 2013-09-07T10:01:04Z
(In reply to comment #0) > This code fails to compile because the struct S implement opAssign and the > compiler tries using it rather than the associative arrays insert. > > void main() { > S[string] ss; > S s; > > ss["hello"] = s; > } > > struct S { > void opAssign(int i) { > } > } > > test.d(6): Error: function test.S.opAssign (int i) is not callable using > argument types (S) > test.d(6): Error: cannot implicitly convert expression (s) of type S to int > test.d(6): Error: function test.S.opAssign (int i) is not callable using > argument types (S) > test.d(6): Error: cannot implicitly convert expression (s) of type S to int > PS C:\Documents and Settings\jphillips\src\Juno> dmd test.d > test.d(5): Error: function test.S.opAssign (int i) is not callable using > argument types (S) > test.d(5): Error: cannot implicitly convert expression (s) of type S to int > test.d(5): Error: function test.S.opAssign (int i) is not callable using > argument types (S) > test.d(5): Error: cannot implicitly convert expression (s) of type S to int From 2.062, the code could work. Even if a struct has only non-identity opAssign methods, identity assignment would be rewritten to the field-to-field assignment. struct S { int val; void opAssign(int i) {} } void main() { S s; S s2; s = s2; // Rewite as: s.tupleof = s2.tupleof; s = 1; // Rewrite as: s.opAssign(1) }