Bug 20808 – [regression] opDispatch error disappears!

Status
NEW
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2020-05-08T15:39:04Z
Last change time
2024-12-13T19:08:30Z
Keywords
accepts-invalid
Assigned to
No Owner
Creator
Adam D. Ruppe
Moved to GitHub: dmd#19701 →

Comments

Comment #0 by destructionator — 2020-05-08T15:39:04Z
With this specific jsvar commit: https://raw.githubusercontent.com/adamdruppe/arsd/643d548245adac27517504a51e3a52a8bc9be69f/jsvar.d and this test program: --- import arsd.jsvar; void printInt(const int value) { assert(0); } void main(string [] args) { var globals = var.emptyObject; globals.printInt = &printInt; //globals["printInt"] = &printInt; } --- That globals.printInt line calls opDispatch. On dmd 2.088, it issued an error Error: function pil.printInt(const(int) value) is not callable using argument types (var, void function(const(int) value)) cannot pass argument globals of type var to parameter const(int) value (which itself is weird, cuz opDispatch frequently gives the useless "no such property" error. so i thought this was a welcome fix but it is still strings) On v2.091.1... it compiles! But does nothing. Obviously it didn't do what it is supposed to do. The commented line there calls opIndexAssign. Note that the implementation of opDispatch forwards directly to opIndexAssign, so if one fails, the other should fail to compile as well. The commented line yields a correct compile error: arsd/jsvar.d(681): Error: cannot modify constant cast(int)__fargs_field_0 arsd/jsvar.d(1355): Error: template instance arsd.jsvar.var.opAssign!(void function(const(int))) rror instantiating arsd/jsvar.d(1311): instantiated from here: opIndexAssign!(void function(const(int))) pil.d(12): instantiated from here: opIndexAssign!(void function(const(int) value)) arsd/jsvar.d(1319): Error: template instance arsd.jsvar.var.__ctor!(void function(const(int))) error instantiating pil.d(12): instantiated from here: opIndexAssign!(void function(const(int) value)) So opDispatch is completely swallowing a compile error in this version that it used to treat differently before. Something weird is going on but I haven't figured out how to reduce it from the full library yet.
Comment #1 by moonlightsentinel — 2020-05-08T20:27:29Z
Reduced example: ==================================== struct var { @property opDispatch(string file, T)(T) // if (is(T==char)) {} } void main() { var globals; globals.printInt = 2; } =================================== Removing `string file` pr enabling the template constraints makes DMD issue a proper error message: => main.d(12): Error: no property printInt for type main.var
Comment #2 by b2.temp — 2020-08-05T18:18:52Z
the reducted version is not good, dont take it to work on a fix. It's is perfectly normal that it is accepted: --- struct var { @property void opDispatch(string file, T)(T t) //if (is(T==char)) { assert(t == 2); } } void main() { var globals; globals.printInt = 2; // this and globals.opDispatch!("printInt") = 2; // that are the same } --- Then when the constraint is enabled, it's perfectly normal that the code is rejected, i.e per convertion rules. Finally when `string file` is missing, this is also rejected as expected because the template cant dispatch the "printInt" pseduo member.
Comment #3 by b2.temp — 2020-08-05T18:25:40Z
Are you sure that this report is not rather invalid, e.g before 2.088 it used to be a reject-valid and now i t's accepted as expected ?
Comment #4 by destructionator — 2020-08-05T18:33:52Z
It modifies a const inside the opAssign which is why it fails. That's not supposed to be allowed so the error should happen. All opDispatch does is forward directly to opIndexAssign, so if opIndexAssign doesn't compile, opDispatch shouldn't either. You can call the assigned function by adding globals.printInt()(); // be sure to use double parens thanks @property if you take that const off the function definition, it works fine in either case showing the assignment was successful. But the const back on and you get error in the direct opIndexAssign and... silence on opDispatch. You can even do globals.opDispatch!"printInt" = &printInt; to get the error.
Comment #5 by razvan.nitu1305 — 2022-02-16T12:10:48Z
(In reply to Adam D. Ruppe from comment #4) > It modifies a const inside the opAssign which is why it fails. That's not > supposed to be allowed so the error should happen. > > All opDispatch does is forward directly to opIndexAssign, so if > opIndexAssign doesn't compile, opDispatch shouldn't either. > > You can call the assigned function by adding > > globals.printInt()(); // be sure to use double parens thanks @property > > if you take that const off the function definition, it works fine in either > case showing the assignment was successful. But the const back on and you > get error in the direct opIndexAssign and... silence on opDispatch. > > You can even do > > globals.opDispatch!"printInt" = &printInt; > > to get the error. I'm trying to fix this issue, but I am not able to reproduce it. globals["printInt"] = &printInt; compiles just fine for me. Is this issue still actual? Also, a smaller test case would help a lot in narrowing down the issue.
Comment #6 by destructionator — 2022-02-16T12:12:44Z
"it compiles just fine" IS the bug. It suppresses an error that should have terminated the compilation.
Comment #7 by destructionator — 2022-02-16T12:14:21Z
BTW also don't forget this related thing: https://issues.dlang.org/show_bug.cgi?id=14145
Comment #8 by razvan.nitu1305 — 2022-02-16T12:14:45Z
(In reply to Adam D. Ruppe from comment #6) > "it compiles just fine" IS the bug. It suppresses an error that should have > terminated the compilation. What I was saying is that both: globals.printInt = &printInt; globals["printInt"] = &printInt; are compiling.
Comment #9 by destructionator — 2022-02-16T12:53:28Z
Oh, I think I linked to the wrong commit. Take that jsvar and modify line 681 to fargs[idx] = args[idx].get!(typeof(a)); so removing the cast to Unqual. Now compile it: --- import arsd.jsvar; void printInt(const int value) { assert(0); } void main(string [] args) { var globals = var.emptyObject; globals.printInt = &printInt; //globals["printInt"] = &printInt; globals.printInt()(5); } --- No error. Run it, no assert. Switch to the [] index version: --- $ dmd a.d jsvar.d jsvar.d(681): Error: cannot modify `const` expression `__fargs_field_0` jsvar.d(1355): Error: template instance `arsd.jsvar.var.opAssign!(void function(const(int)))` error instantiating jsvar.d(1311): instantiated from here: `opIndexAssign!(void function(const(int)))` a.d(12): instantiated from here: `opIndexAssign!(void function(const(int) value))` jsvar.d(1319): Error: template instance `arsd.jsvar.var.__ctor!(void function(const(int)))` error instantiating a.d(12): instantiated from here: `opIndexAssign!(void function(const(int) value))` --- So problem still there on 2.098.0
Comment #10 by robert.schadek — 2024-12-13T19:08:30Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/19701 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB