digitalmars.D - Bug in compiler?
- Shachar Shemesh (25/25) Dec 15 2014 Please consider the following program:
- ketmar via Digitalmars-d (12/44) Dec 15 2014 yes, this is due to `lazy` in assrtThrown. what `lazy` does is actually
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (3/54) Dec 15 2014 Another point against storage class ref.
- John Colvin (3/64) Dec 15 2014 Perhaps. I would say lazy should be clever enough to work this
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. Help? Shachar
Dec 15 2014
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; =20 void main() { struct A { int a; =20 disable this(this); disable ref A opAssign(const ref A); =20 ref A opOpAssign(string op: "~")(int data) { a +=3D data; =20 return this; } } =20 auto a =3D A(2); =20 a ~=3D 3; =20 assertThrown!Exception(a ~=3D 3); } =20 Compilation (dmd 2.066.1) fails on the assertThrown line: Error: struct test.main.A is not copyable because it is annotated with=20 disable =20 What I do not understand is why A should need to be copyable. Where is=20 the copy made? I'm guessing this is because of the lazy definition of=20 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 ~=3D 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.
Dec 15 2014
On Monday, 15 December 2014 at 14:33:51 UTC, ketmar via Digitalmars-d wrote:On Mon, 15 Dec 2014 16:01:35 +0200 Shachar Shemesh via Digitalmars-d <digitalmars-d puremagic.com> wrote:Another point against storage class ref.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.
Dec 15 2014
On Monday, 15 December 2014 at 15:00:56 UTC, Marc Schütz wrote:On Monday, 15 December 2014 at 14:33:51 UTC, ketmar via Digitalmars-d wrote:Perhaps. I would say lazy should be clever enough to work this out.On Mon, 15 Dec 2014 16:01:35 +0200 Shachar Shemesh via Digitalmars-d <digitalmars-d puremagic.com> wrote:Another point against storage class ref.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.
Dec 15 2014