On Mon, 15 Dec 2014 16:01:35 +0200 Shachar Shemesh via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> Please consider the following program: > import std.exception; > > void main() > { > struct A { > int a; > > @disable this(this); > @disable ref A opAssign(const ref A); > > ref A opOpAssign(string op: "~")(int data) { > a += data; > > return this; > } > } > > auto a = A(2); > > a ~= 3; > > assertThrown!Exception(a ~= 3); > } > > Compilation (dmd 2.066.1) fails on the assertThrown line: > Error: struct test.main.A is not copyable because it is annotated with > @disable > > What I do not understand is why A should need to be copyable. Where is > the copy made? I'm guessing this is because of the lazy definition of > the expression, but still I don't see any reason to create a copy. yes, this is due to `lazy` in assrtThrown. what `lazy` does is actually creating a lambda. then compiler tries to deduce the type of the expression and it got `A`. so it generates the code like `A expression`. it can't see `ref` there, as `a` type is `A`, not `ref A`. you can workaround that with creating the necessary lambda manually: assertThrown!Exception((ref A aa) { aa ~= 3; }(a)); tl;dr: no, it's not a bug in the compiler. but the error message is misleading and you are required to understang some internals to make sense out of it.
signature.asc
Description: PGP signature