Bug 18985 – bad error message for += operation on shared Object

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2018-06-14T06:11:49Z
Last change time
2018-06-21T08:42:38Z
Keywords
diagnostic
Assigned to
No Owner
Creator
OlegZ

Attachments

IDFilenameSummaryContent-TypeSize
1705evt.dfor 3) pointtext/plain1610

Comments

Comment #0 by black80 — 2018-06-14T06:11:49Z
Created attachment 1705 for 3) point class Some { static immutable Some One = new immutable Some(); auto opOpAssign( op )( Some val ) { writefln( "Some.op" ~ op ); } } auto var = new shared Some(); var += Some.One; // and we'v got here: Error: read-modify-write operations are not allowed for `shared` variables. Use `core.atomic.atomicOp!"+="(var, One)` instead. 1) this error should be a warning only, cause not a beginners usually know what they do. and compiler should allow to do what they want. it shouldn't be taboo. just say your disagreement and compile code. (and should exist possibility disable warning) compiler shouldn't say "no!" in negotiation with people in case when it still can to compile fucking code 2) this error is stupid cause we can't use atomicOp for user defined type (in most cases) 3) "shared" keyword is stupid thing in D. it should be used for only one thing - tell compiler to store variable NOT in TLS. imagine Event(R,Args...) with +=/-= ops. usually it should be shared variables with synchronized methods(that automatically became shared. WTF?). when u try to use this event dmd raised many errors about I can't use usual delegate for op+= with shared variable. when one thing shared compiler tells that all things should be shared. crazy. it's like falling dominos - compiler don't allow write program that works in another language. too smart compiler is calamity. attachment has some Event implementation try to compile auto evt = new /*SHARED*/ Event!(void, string)(); evt += delegate void(string s) { writeln( s ); } and hello dozen errors 4) synchronized method(became shared) differ from methods with auto meth(...) { synchronized( this ) { ... } } meaning is same but behavior is not same - WTF? context for shared method is very different and we have many errors for nothing. well, it's still stupid "shared" 5) offtopic: but another stupid thing with too smart compiler (string s) => s.length which means int function(string) (string s) => { return s.length; } which means int delegate() function(string) well, it looks same BUT in D this is not same I can't imagine where I need lambda that return lambda BUT I can ask compiler for that by myself (string s) => { return () => s.length; } that's all! return to me delegate! I want it! why compiler do work that I didn't ask him? why people should to remember when u use "=>" with "{" and "return }" u will get another implicit lambda? JavaScript/C# compile code above equals. why D should compile it in fucking meaningless style? image about good and bad code (well, my Event maybe too many WTF for u too, but u ask me to fight with compiler not to friend with him) https://i2.wp.com/commadot.com/wp-content/uploads/2009/02/wtf.png?resize=550%2C433
Comment #1 by ag0aep6g — 2018-06-14T14:07:06Z
(In reply to OlegZ from comment #0) > class Some { > static immutable Some One = new immutable Some(); > auto opOpAssign( op )( Some val ) { writefln( "Some.op" ~ op ); } > } > auto var = new shared Some(); > var += Some.One; > // and we'v got here: Error: read-modify-write operations are not allowed > for `shared` variables. Use `core.atomic.atomicOp!"+="(var, One)` instead. There a couple errors in your opOpAssign. If you implement it correctly, you don't get an error: ---- class Some { static immutable Some One = new immutable Some(); auto opOpAssign( string op )( const Some val ) shared { import std.stdio: writefln; writefln( "Some.op" ~ op ); } } void main() { auto var = new shared Some(); var += Some.One; /* no error */ } ---- But the "read-modify-write" error you got is wrong/confusing. It should be fixed. A simplified test for the bad error message: ---- Object foo; shared Object bar; void main() { foo += 1; /* Error: foo += 1 is not a scalar, it is a object.Object */ bar += 1; /* Error: read-modify-write operations are not allowed for shared variables. Use core.atomic.atomicOp!"+="(bar, 1) instead. */ } ---- The first error message is a bit weird (shouldn't it say "foo is not a scalar"?), but one can figure out the meaning. The second error message is bad. `shared` is a red herring. Would be better if the first message would be displayed here, too. > 1) this error should be a warning only, cause not a beginners usually know > what they do. and compiler should allow to do what they want. By that logic these should also be warnings instead of errors: 1) assignment as a condition: int x; if (x = 1) {} 2) narrowing conversions: long x; int y; y = x; 3) all the @safe checks: void main() @safe { int* p = void; } You see that's not how D rolls. But you can usually tell the compiler to "just do it" by using the unsafe tools `cast` and `@trusted`. In the case of `shared`, you can always cast it away and do whatever you want then. > 2) this error is stupid cause we can't use atomicOp for user defined type > (in most cases) Yup. The error message is bad. > 3) "shared" keyword is stupid thing in D. Bugzilla is not particularly suited for rants about how D sucks. The General section of the forum is the right place for that. https://forum.dlang.org/group/general > 4) synchronized method(became shared) differ from methods with > auto meth(...) { synchronized( this ) { ... } } > meaning is same but behavior is not same - WTF? This isn't directly related to the opOpAssign thing anymore, is it? If there's something wrong with `synchronized`, please file a separate issue. Or maybe make a thread on the forum first to find out if it's worth filing. Might just be a design decision that you don't like. I'm adding the "diagnostic" keyword here, because the error message you got is confusing and could be improved. I'm changing the title reflect that the error message is the problem. I'm reducing the severity to "normal", because the error message is all that needs fixing here. The code works if opOpAssign is written correctly.
Comment #2 by black80 — 2018-06-14T15:17:09Z
yes, the error disappeared. for non-shared vars should be used non-shared method overloading (when it needed) or non-shared another class. not easy. and about to change wrong error text I filled before another bug/enhancement https://issues.dlang.org/show_bug.cgi?id=18961 (second comment)
Comment #3 by black80 — 2018-06-14T15:18:01Z
yes, the error disappeared. for non-shared vars should be used non-shared method overloading (when it needed) or non-shared another class. not easy. and about to change wrong error text I filled before another bug/enhancement https://issues.dlang.org/show_bug.cgi?id=18961 (second comment)
Comment #4 by razvan.nitu1305 — 2018-06-15T12:05:03Z
AnyObject foo; shared AnyObject bar; void main() { foo += 1; /* Error: foo += 1 is not a scalar, it is a object.Object */ bar += 1; /* Error: read-modify-write operations are not allowed for shared variables. Use core.atomic.atomicOp!"+="(bar, 1) instead. */ } We can distinguish 4 situations here: 1. AnyObject does not define any opOpAssign methods => error message should be in both situations "$object is not scalar" 2. Anyobject does define opOpAssign but it's not shared => foo passes compilation, but bar does not and the most helpful error message would be "read-modify-write operations are not allowed for shared variables. Use core.atomic.atomicOp!"+="(bar, 1) instead or implement a shared opOpAssign for type AnyObject" 3. AnyObject defines opOpAssign shared but not normal opOpAssign => foo += 1 fails with "object is not scalar message" and bar works. 4. AnyObject defines both shared/non-shared opOpAssign => both examples compile
Comment #5 by razvan.nitu1305 — 2018-06-15T13:10:21Z
Comment #6 by github-bugzilla — 2018-06-21T08:42:37Z
Commits pushed to master at https://github.com/dlang/dmd https://github.com/dlang/dmd/commit/ff23072e11750a83da1078705a16f7d160e793d9 Fix Issue 18985 - bad error message for += operation on shared Object https://github.com/dlang/dmd/commit/f6a4a949d24e3174149069c855d67f52fb31c71c Merge pull request #8360 from RazvanN7/Issue_18985 Fix Issue 18985 - bad error message for += operation on shared Object