-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Don't use NonNull::dangling as sentinel value in Rc, Arc #52637
Conversation
Instead, rely on alignment and use usize::MAX as sentinel.
src/liballoc/rc.rs
Outdated
// `Weak::new` sets this to a dangling pointer so that it doesn’t need | ||
// to allocate space on the heap. | ||
// `Weak::new` sets this to `usize::MAX` so that it doesn’t need | ||
// to allocate space on the heap. That's not a value a real poiner |
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.
typo, poiner -> pointer
@@ -449,6 +450,8 @@ impl<T: ?Sized> Rc<T> { | |||
#[stable(feature = "rc_weak", since = "1.4.0")] | |||
pub fn downgrade(this: &Self) -> Weak<T> { | |||
this.inc_weak(); | |||
// Make sure we do not create a dangling Weak | |||
debug_assert!(!is_dangling(this.ptr)); |
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.
this assert is not gonna show up in libstd for users. Libstd is compiled in release mode
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.
We have tests using the debug profile in the CI, so keeping this is fine.
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.
Yeah, I didn't want to risk an actual perf hit (though it should get all optimized out, because LLVM knows the pointer to be aligned).
src/liballoc/sync.rs
Outdated
// to allocate space on the heap. | ||
// `Weak::new` sets this to `usize::MAX` so that it doesn’t need | ||
// to allocate space on the heap. That's not a value a real poiner | ||
// will ever have because RcBox has alignment at least 4. |
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.
Technically at least 2 due to 16-bit targets
@@ -1185,15 +1189,14 @@ impl<T> Weak<T> { | |||
#[stable(feature = "downgraded_weak", since = "1.10.0")] | |||
pub fn new() -> Weak<T> { | |||
Weak { | |||
ptr: NonNull::dangling(), | |||
ptr: NonNull::new(usize::MAX as *mut RcBox<T>).expect("MAX is not 0"), |
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 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.
Better than unsafe code, I figured. :P
Fixed typos. |
@bors r+ |
📌 Commit a303741 has been approved by |
Don't use NonNull::dangling as sentinel value in Rc, Arc Instead, rely on alignment and use usize::MAX as sentinel. Cc rust-lang#52508 r? @joshtriplett
Rollup of 10 pull requests Successful merges: - #52538 (Remove obsolete flags in the i586_musl Dockerfile) - #52548 (Cursor: update docs to clarify Cursor only works with in-memory buffers) - #52605 (Do not suggest using `to_owned()` on `&str += &str`) - #52621 (Fix color detection for Windows msys terminals.) - #52622 (Use MultiSpan in E0707 and E709) - #52627 (Compile rustc before building tests for rustdoc) - #52637 (Don't use NonNull::dangling as sentinel value in Rc, Arc) - #52640 (Forget Waker when cloning LocalWaker) - #52641 (Simplify 2 functions in rustc_mir/dataflow) - #52642 (Replace a few expect+format combos with unwrap_or_else+panic) Failed merges: r? @ghost
Is it ok to use a misaligned pointer? |
Of course! |
Then why did we change zero-size |
Containers of ZSTs can be iterated over by reference (Vec directly, Box e.g. via |
Uh, iteration is probably an unnecessary complication. Just Deref'ing them will already give you a reference that has to be aligned. |
I see, thanks for the explanation! |
Instead, rely on alignment and use usize::MAX as sentinel.
Cc #52508
r? @joshtriplett