-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Small refactoring to make this code more clear #30593
Conversation
r? @brson (rust_highfive has picked a reviewer for you, use r? to override) |
@bors r+ rollup |
📌 Commit a1f3781 has been approved by |
@bors: r- |
This failed with a segfault on travis. I thought that my local build worked, double checking now. |
Wow, this does segfault locally, and also with this small second change that @aturon pointed out. Maybe there is some kind of magic in the original mess there... |
re-reading again, I noticed that there was one level of indirection at one arm, and another at the other arm. So I did this third commit, and it also segfaults. At this point, I'm just wondering what magic here is causing this... |
if ptr as *mut u8 as usize == 0 || ptr as *mut u8 as usize == mem::POST_DROP_USIZE { | ||
let thin = ptr as *const (); | ||
|
||
if !thin.is_null() && thin as usize != mem::POST_DROP_USIZE { |
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.
Why did you invert the condition?
It should either be if thin.is_null() || thin as usizee == mem::POST_DROP_USIZE
or if !(!thin.is_null() && thin as usize != mem::POST_DROP_USIZE)
. What you wrote is not equivalent to the old code.
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.
... because even simple code is hard. that'd do it, i'd bet.
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.
Would it make sense to abstract the condition to a function, so that it can be given a name and re-used? The code itself is trivial, but it's still easy to get it wrong. if already_dropped(ptr) { return; }
(or any other better name) would be easy to read and convey the information about what is going on in both places (currently the check at https://github.com/steveklabnik/rust/blob/small_rc_refactoring/src/liballoc/arc.rs#L715 refers to the comment of the other code fragment, which finally explains what is going on).
This no longer segfaults, but it still fails several Arc tests. I have to run, I will fix the tests in the morning. I'm sure I just did something else dumb, time to bust out some truth tables. |
e1caee1
to
b5b2602
Compare
Okay! Finally got it to pass. I was just being silly. I've squashed and rebased everything. |
Is the fact that the two files are divergent intentional? |
They were before I got here. |
Is there a reason to preserve the divergence? |
ptr as *const () as usize != mem::POST_DROP_USIZE { | ||
let thin = ptr as *const (); | ||
|
||
if !(thin as *const *const ()).is_null() && thin as usize != mem::POST_DROP_USIZE { |
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.
In particular this cast to *const *const ()
seems pointless?
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 had re-added it when @aturon pointed out that I was missing the second level. I thought it was pointless, but I thought it might have been causing the segfaults.
On Dec 29, 2015, 19:30 -0500, Alexis Beingessnernotifications@github.com, wrote:
Insrc/liballoc/rc.rs(#30593 (comment)):
@@ -782,8 +782,9 @@ impl<T: ?Sized>Drop for Weak{>fn drop(&mut self) {>unsafe {>let ptr = _self.ptr;>- if !((&ptr as *const _ as *const *const ())).is_null()&&>- ptr as *const () as usize != mem::POST_DROP_USIZE {>+ let thin = ptr as *const ();>+>+ if !(thin as *const *const ()).is_null()&&thin as usize != mem::POST_DROP_USIZE {
In particular this cast seems pointless?
—
Reply to this email directly orview it on GitHub(https://github.com/rust-lang/rust/pull/30593/files#r48580830).
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.
If it's causing the segfaults, this should be filed as a bug.
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.
There's a bug open for it generally, I think #30577
but I'm not sure yet, as I didn't really dig into the why.
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.
It does work without this cast. PR updated.
No, other than I'm not the person to write that patch, just trying to do a small cleanup here. |
b5b2602
to
cd03c83
Compare
Is there any reason why the comparisons at https://github.com/steveklabnik/rust/blob/cd03c83330df5aa9a030b632e80e6675e26615ec/src/liballoc/arc.rs#L715 and https://github.com/steveklabnik/rust/blob/cd03c83330df5aa9a030b632e80e6675e26615ec/src/liballoc/rc.rs#L452 are not updated as well? Should that be in another PR? |
Only because I didn't notice them! I'll do that right now. |
@gankro oh, did you mean the divergence of the |
The & vs | divergence I'm kinda fine with preserving. iirc it "makes sense" for each drop impl. |
Okay, so this is very strange: diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 9109e9d..8318607 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -784,7 +784,7 @@ impl<T: ?Sized> Drop for Weak<T> {
let ptr = *self._ptr;
let thin = ptr as *const ();
- if !thin.is_null() && thin as usize != mem::POST_DROP_USIZE {
+ if thin.is_null() || thin as usize == mem::POST_DROP_USIZE {
self.dec_weak();
// the weak count starts at 1, and will only go to zero if all
// the strong pointers have disappeared. This diff causes a segfault. |
That's because it's the exact opposite of the check. You now dec_weak only if the pointer is null or dropped. You left out a negation in your demorgans. |
Oh duh. It still probably shouldn't segfault, but yes, I am just being dumb. :( |
Nah derefing null/dangling ptrs is pretty much the definition of "should segfault" |
I guess this is unsafe. I should like, not write code until 2pm or something. |
5d48ad6
to
88a389c
Compare
I have fixed my errors and also handled the two other places as well. |
88a389c
to
7426f85
Compare
7426f85
to
0182a77
Compare
This hairy conditional doesn't need to be so. It _does_ need to be a thin pointer, otherwise, it will fail to compile, so let's pull that out into a temporary for future readers of the source. Also, after a discussion with @pnkfelix and @gankro, we don't need these null checks anymore, as zero-on-drop has been gone for a while now.
0182a77
to
2cff12e
Compare
@bors r+ WE DID IT |
📌 Commit 2cff12e has been approved by |
⌛ Testing commit 2cff12e with merge 8aee582... |
This hairy conditional doesn't need to be so. It _does_ need to be a thin pointer, otherwise, it will fail to compile, so let's pull that out into a temporary for future readers of the source. /cc @nrc @SimonSapin @gankro @durka , who brought this up on IRC
This hairy conditional doesn't need to be so. It does need to be a
thin pointer, otherwise, it will fail to compile, so let's pull that out
into a temporary for future readers of the source.
/cc @nrc @SimonSapin @gankro @durka , who brought this up on IRC