Templated opAssign cannot be declared in a struct with copy constructor.
-------------------- test.d
struct S
{
this(this) {}
void opAssign(T)(T rhs) if (! is(T == S))
{}
}
--------------------
% dmd -o- -c test
test.d: Error: function test.S.opAssign conflicts with template test.S.opAssign(T) if (!is(T == S)) at test.d(4)
--------------------
Comment #1 by andrei — 2010-07-04T15:19:12Z
That's an important issue. I just committed a fix to Tuple that replaces opAssign with assign, but that should only be considered a workaround.
Comment #2 by clugdbug — 2010-09-23T00:09:42Z
Don't have a full patch yet, but this is where the problem is.
clone.c, StructDeclaration::buildOpAssign().
Parameter *param = new Parameter(STCnodtor, type, Id::p, NULL);
Parameters *fparams = new Parameters;
fparams->push(param);
Type *ftype = new TypeFunction(fparams, handle, FALSE, LINKd);
#if STRUCTTHISREF
((TypeFunction *)ftype)->isref = 1;
#endif
fop = new FuncDeclaration(0, 0, Id::assign, STCundefined, ftype);
+ Dsymbol *s = search_function(this, Id::assign);
+ TemplateDeclaration *td = s ? s->isTemplateDeclaration() : NULL;
+ if (td)
+ { // we need to make a template function instead
Comment #3 by k.hara.pg — 2011-04-28T12:53:39Z
Created attachment 955
test cases
Patch created:
https://github.com/9rnsr/dmd/compare/master...fix4424
Behaviors:
- if template opAssign exists, check it is identity opAssign.
- if template identity opAssign need, following opAsign build:
ref S opAsign(T:S)(T s) if (is(T == S))
{
T tmp = this; // bit copy
this = s; // bit copy
tmp.dtor();
return this;
}
- no changes with non tempate opAssign.
Comment #4 by cristi.cobzarenco — 2011-08-16T14:03:26Z
*** Issue 7427 has been marked as a duplicate of this issue. ***
Comment #6 by dmitry.olsh — 2012-08-01T14:28:56Z
I've hit this one today and failed to workaround it in any acceptable way.
Comment #7 by code — 2012-10-03T07:04:16Z
(In reply to comment #6)
> I've hit this one today and failed to workaround it in any acceptable way.
This is the workaround used in phobos, it works pretty well for me too.
private mixin template _workaround4424()
{
@disable void opAssign(typeof(this) );
}
mixin _workaround4424;