-
-
Notifications
You must be signed in to change notification settings - Fork 521
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
refactor(traverse): simplify pointer manipulation and improve readability #9162
Conversation
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
CodSpeed Performance ReportMerging #9162 will not alter performanceComparing Summary
|
4cc4045
to
02de379
Compare
02de379
to
c66d4c0
Compare
fd54a83
to
c956a60
Compare
c66d4c0
to
6eb0f09
Compare
56e969f
to
d3142b2
Compare
6eb0f09
to
c7945c2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am pretty sure this change will cause undefined behavior.
There's a subtle difference between these 3:
(assume ptr
is a *const Program
)
&*( (ptr as *const u8).add( offset_of!(Program, span) ) as *const Span )
&*addr_of!( (*ptr).span )
&(&*ptr).span
(1) is what we have now, and (2) should be equivalent (if my understanding is correct).
They both convert the pointer to Program
into a pointer to the Span
, without creating a &Program
reference in between.
But this PR uses something similar to (3), which is different from the first 2 because it creates an intermediate &Program
reference (the &*ptr
part deferences pointer *const Program
to &Program
).
And that's exactly what we need to avoid, because there already exists a live &mut Program
- and holding a &
reference and a &mut
reference to the same thing is a violation of Rust's aliasing rules.
At least this is my understanding. And this is why I'm so cautious about touching Traverse
- because it's really at the edges of my understanding. I know enough to be aware that there are subtleties, but I'm not sure if I understand them all. For example, the docs talk about a "value" and a "place" being different, but what exactly is that difference?
The good news is... now that you've removed AstBuilder::copy
, we are finally in a position to deploy Miri and find out!
I propose to put this PR on hold for now. Next week I'd like to run the entire transformer conformance suite under Miri (which is slooooow - may take something like 12 - 48 hours) and we can find out whether it's sound in its current state. If it is, then we can look at modifying it, and then test again.
I'm going to mark this PR as "draft" in the meantime.
(sorry this is an incomplete explanation - I don't mean to invoke mysterious "dark magic" and avoid explaining myself - it's just really hard to put into words when I don't have a completely clear mental model myself)
close: oxc-project/backlog#17
I don't know too much about raw pointers, the benchmark shows no difference both ways. I don't use addr_of because the documentation has noted this API has been soft-deprecated