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
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