Make lambda symbols stable post a3abf1187ec019fac1ae98ffe78d68d7523b5665#17102
Make lambda symbols stable post a3abf1187ec019fac1ae98ffe78d68d7523b5665#17102dkorpel merged 1 commit intodlang:masterfrom
Conversation
|
Thanks for your pull request and interest in making D better, @yanok! 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 referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + dmd#17102" |
|
/cc @dkorpel |
|
Looks good so far, are you going to make use of it or is that for a next Pull Request? |
I definitely want this for our local branch:
But I also think it's the right thing to merge into the main branch as well, since it finally stabilize lambda symbols across compilation unit. |
|
But in this Pull Request, the new |
Ouch, you are right, sorry. Must have been lost with the merge. Let me add it back and update the PR. |
5436517 to
44429c2
Compare
dkorpel
left a comment
There was a problem hiding this comment.
Do you have a test case for this?
I have a nice small test case for lambda getting another name, but that example works in a sense: the lambda just gets emitted twice, but the binary links and runs. So I can only detect it with |
Probably, but I'm not a fan of shell tests for specific implementation details, because they break easily and are hard to debug. I was hoping maybe there's an easy |
It's a cool idea! Unfortunately I've tried and failed :( We need a mangle of a lambda/delegate literal, but it looks like |
|
UPD: I've managed to make an example with |
Commit a3abf11 fixes some cases of lambdas having unstable symbol names between compilation units by using `generateIdWithLoc` to generate stable lambda names, however since LOC doesn't uniquely identify a lambda instance (because templates, mixins, static foreach and foreach unrolling), `generateIdWithLoc` adds a counter, so there is still some instability going on. `generateIdWithLoc` makes the name uniq per file+loc, by adding adding a numeric suffix. But the order of instantiations might be different across compilation units, so with this counting scheme we are back to unstable names, so one module might have `t!0.__lambda_LOC` and `t!1.__lambda_LOC_1` while another one has `t!1.__lambda_LOC` This is not a critical problem, but at very least the code gets duplicated for no reason. I also have an example where it leads to linking error, but since it's not a small one and fails to minimize further, I suspect it's a result of interaction with some other bug. The thing is we don't even need uniqueness for those lambdas inside templates/mixins: their final names will have the instantiation prefix anyway. But we can't also just disable this uniqueness check completely: `static foreach` as well as unrollings of the normal `foreach` with lambdas in the loop body will have several copies of a single lambda with the same file+loc. So here we do want to keep making them unique. Fortunately, I don't think a `foreach` could be iterated in different order in different compilation units, so hopefully if we limit the counting to this case only, it won't make symbols unstable. To implement this idea, I've added an extra `parent` argument to `generateIdWithLoc`: it works like using `parent ~ prefix` prefix, but without adding `parent` to the final output. Fixes since last review: 1. Changed `fromStringz` to `toDString` 2. Added a test to showcase the problem
Added a test, PTAL. |
|
LGTM |
|
This approach apparently suffers from unstable |
@kinke Uh.. sorry for the mess. I think comparing by reference should generally work too... my only concern are template instances, maybe we have to pass Can't we get the mangle of |
|
Thx, that's a good idea I think - pushed as 2nd commit in #21343. |
…al), to prevent linker errors for separate compilation case where the lambda is not emitted (because supposedly already emitted in linked library). Internal linkage breaks that assumption (because not linkable by other module). Lambda mangles should be stable now, because of dlang/dmd#17102 (and related earlier fixes).
…al), to prevent linker errors for separate compilation case where the lambda is not emitted (because supposedly already emitted in linked library). Internal linkage breaks that assumption (because not linkable by other module). Lambda mangles should be stable now, because of dlang/dmd#17102 (and related earlier fixes).
Commit a3abf11 fixes some cases of lambdas having unstable symbol names between compilation units by using
generateIdWithLocto generate stable lambda names, however since LOC doesn't uniquely identify a lambda instance (because templates, mixins, static foreach and foreach unrolling),generateIdWithLocadds a counter, so there is still some instability going on.generateIdWithLocmakes the name uniq per file+loc, by adding adding a numeric suffix. But the order of instantiations might be different across compilation units, so with this counting scheme we are back to unstable names, so one module might havet!0.__lambda_LOCandt!1.__lambda_LOC_1while another one has
t!1.__lambda_LOCThis is not a critical problem, but at very least the code gets duplicated for no reason. I also have an example where it leads to linking error, but since it's not a small one and fails to minimize further, I suspect it's a result of interaction with some other bug.
The thing is we don't even need uniqueness for those lambdas inside templates/mixins: their final names will have the instantiation prefix anyway. But we can't also just disable this uniqueness check completely:
static foreachas well as unrollings of the normalforeachwith lambdas in the loop body will have several copies of a single lambda with the same file+loc. So here we do want to keep making them unique. Fortunately, I don't think aforeachcould be iterated in different order in different compilation units, so hopefully if we limit the counting to this case only, it won't make symbols unstable.To implement this idea, I've added an extra
parentargument togenerateIdWithLoc: it works like usingparent ~ prefixprefix, but without addingparentto the final output.