-
-
Notifications
You must be signed in to change notification settings - Fork 607
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix for the non-global template issue 5710 #9282
Conversation
Thanks for your pull request and interest in making D better, @SSoulaimane! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + dmd#9282" |
Reference the bug report in regards to fixing bugs please. |
170f67d
to
26cd8fe
Compare
done. |
when you want to go ahead with this, search for examples that it should miscompile. |
Yes. Same template arguments with a different |
54575fc
to
09bb661
Compare
627035e
to
d7d9a92
Compare
This doesn't work: import core.stdc.stdio : printf;
struct Adder
{
int base;
// works
uint addBaseCallFunc(alias func)(uint value)
{
return func(base + value);
}
// these 2 don't work
uint willNeedThreeContextPtrs(alias func)(uint value)
{
int localVar = func(value);
uint localFunc(uint subValue) { return localVar + subValue; }
return addBaseCallFuncs!(func, localFunc)(value);
}
uint addBaseCallFuncs(alias func1, alias func2)(uint value)
{
return func2(func1(base + value));
}
}
void main()
{
auto adder = Adder(3);
int offset = 6;
uint doOffset(uint value) { return offset + value; }
// works
printf("%d\n", adder.addBaseCallFunc!doOffset(4));
// need 3 context pointers (doesn't work)
printf("%d\n", adder.willNeedThreeContextPtrs!doOffset(4));
} |
Here's another one that seems to compile, but fails at runtime (it doesn't print anything): import core.stdc.stdio : printf;
struct Adder
{
int base;
uint addBaseCallFuncs(alias func1, alias func2)(uint value)
{
return func2(func1(base + value));
}
}
void main()
{
auto adder = Adder(3);
int offset = 6;
uint doOffset1(uint value) { return offset + value; }
void anotherFunc()
{
int anotherVar = 11;
uint doOffset2(uint value) { return anotherVar + value; }
printf("%d\n", adder.addBaseCallFuncs!(doOffset1, doOffset2)(4));
}
} |
7a9c5d7
to
30a72ac
Compare
@marler8997 good catch! |
f34b136
to
942e0c5
Compare
8d94a77
to
23e6981
Compare
Nothing unusually complex.
Nothing is rewritten. Just making a
I'm not familiar enough with gdb but I responded earlier.
That was the initial strategy but I dropped it because it was not going to be seamless for the users.
I'm not familiar with the gdb backend but the frontend is shared. |
Breaking already working compilers is a complex change.
Why? You could have just added a
That is no excuse to be breaking other people's code. |
It's not supposed to break existing code.
I dropped that solution, It was easy to implement but it entailed subtle symbol and type quirks. It was not possible to new classes (without involving expressions in the type semantic). And types were on jeopardy, types would mismatch if found under instantiations which were made with different Example: struct S
{
auto inner(alias a)()
{
class I {}
return new I;
}
unittest
{
// type mismatch
auto a = 0; // if changed to enum a = 0; the error goes away
auto obj0 = S();
auto obj1 = S();
alias I0 = typeof(obj0.inner!a());
alias I1 = typeof(obj1.inner!a());
static assert(is(I0 == I1)); // error
}
} |
Bugs in type merging have been reported a while back, and need to be addressed, not constantly worked around by adding more to the pile. |
Sure but this was an inevitable design decision problem that I can't see ever being solved because with that strategy the instantiation trees are in reality different from the AST to mangling to the codegen. In short you either add more work and hacks to the frontend or to the backend and I chose the cleaner solution for the user. I don't mind extra work. This issue was dragging it's feet for almost a decade, so just a few more lines of code in the backend to get it right was no big deal at least for me. |
Update C++ headers - Follow up to #9282 merged-on-behalf-of: Nicholas Wilson <[email protected]>
This causes a new ICE, see https://issues.dlang.org/show_bug.cgi?id=20063 |
|
As long as dlang/dmd#9282 isn't ported to LDC.
As long as dlang/dmd#9282 isn't ported to LDC.
As long as dlang/dmd#9282 isn't ported to LDC.
Looks like it also enables code leading to another ICE wrt. fields from base classes: https://issues.dlang.org/show_bug.cgi?id=20333 |
Thanks. I noticed that issue. It's not an ICE in DMD. Although it appears to be error on valid behaviour. Line 285 in 73be029
|
Thx. I wasn't sure how this is supposed to work, so played with it, and it works fine for a non-inherited field: https://run.dlang.io/is/SEsfqG |
You know what's interesting? At the time, I implemented the logic of |
This was fixed in dlang#9282 (d6139e3).
…7046 This was fixed in dlang#9282 (d6139e3).
This was fixed in dlang#9282 (d6139e3).
This was fixed in dlang#9282 (d6139e3).
Good to go.
I dropped the initial strategy instead I decided to use a static array of two pointer
void*[2]*
and making this one a closure variable thus it will be GC-allocated only when the function escapes.example:
See unittests for exmaples.