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