-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Tracking issue for uninitialized constructors for Box, Rc, Arc #63291
Comments
Just from looking at the current source code: pub fn new_uninit() -> Box<mem::MaybeUninit<T>> {
let layout = alloc::Layout::new::<mem::MaybeUninit<T>>();
let ptr = unsafe {
Global.alloc(layout)
.unwrap_or_else(|_| alloc::handle_alloc_error(layout))
};
Box(ptr.cast().into())
} When
Did I have overseen something or is this a bug? |
Good point! I copied this pattern from
|
I have noticed this when implementing This is my implementation for the sliced version. |
Requesting a zero-size allocation is not allowed, return a dangling pointer instead. CC rust-lang#63291 (comment)
Fix zero-size uninitialized boxes Requesting a zero-size allocation is not allowed, return a dangling pointer instead. CC rust-lang#63291 (comment)
Fix zero-size uninitialized boxes Requesting a zero-size allocation is not allowed, return a dangling pointer instead. CC rust-lang#63291 (comment)
Fix zero-size uninitialized boxes Requesting a zero-size allocation is not allowed, return a dangling pointer instead. CC rust-lang#63291 (comment)
Fix zero-size uninitialized boxes Requesting a zero-size allocation is not allowed, return a dangling pointer instead. CC rust-lang#63291 (comment)
alloc: Add new_zeroed() versions like new_uninit(). MaybeUninit has both uninit() and zeroed(), it seems reasonable to have the same surface on Box/Rc/Arc. Needs tests. cc rust-lang#63291
What are the requirements for stabilizing the I don't think using |
Yes, that’s exactly the idea with having |
Great! I still think it'd be better to provide safe abstraction for it, but at least it'd be possible to do in a library. |
Similar to |
Add missing try_new_uninit_slice_in and try_new_zeroed_slice_in The methods for fallible slice allocation in a given allocator were missing from `Box`, which was an oversight according to rust-lang/wg-allocators#130 This PR adds them as `try_new_uninit_slice_in` and `try_new_zeroed_slice_in`. I simply copy-pasted the implementations of `try_new_uninit_slice` and `try_new_zeroed_slice` and adusted doc comment, typings, and the allocator it uses internally. Also adds missing punctuation to the doc comments of `try_new_uninit_slice` and `try_new_zeroed_slice`. Related issue is rust-lang#32838 (Allocator traits and std::heap) *I think*. Also relevant is rust-lang#63291, but I did not add the corresponding `#[unstable]` proc macro, since `try_new_uninit_slice` and `try_new_zeroed_slice` are also not annotated with it.
Rollup merge of rust-lang#127415 - AljoschaMeyer:master, r=dtolnay Add missing try_new_uninit_slice_in and try_new_zeroed_slice_in The methods for fallible slice allocation in a given allocator were missing from `Box`, which was an oversight according to rust-lang/wg-allocators#130 This PR adds them as `try_new_uninit_slice_in` and `try_new_zeroed_slice_in`. I simply copy-pasted the implementations of `try_new_uninit_slice` and `try_new_zeroed_slice` and adusted doc comment, typings, and the allocator it uses internally. Also adds missing punctuation to the doc comments of `try_new_uninit_slice` and `try_new_zeroed_slice`. Related issue is rust-lang#32838 (Allocator traits and std::heap) *I think*. Also relevant is rust-lang#63291, but I did not add the corresponding `#[unstable]` proc macro, since `try_new_uninit_slice` and `try_new_zeroed_slice` are also not annotated with it.
T-libs-api has consensus for stabilizing some of `feature(new_uninit)`, but not for `Box<MaybeUninit<T>>::write`. The replacement is trivial, so let's just do that, and RfL can simply move off the feature after it is stabilized. That will happen immediately after this unblocks Rust CI, as the relevant FCP has completed: rust-lang/rust#63291 (comment) This is required in advance of the stabilization because any remaining unstable API will be carved up into subfeatures as a direct result of stabilizing the majority of it. This code doesn't know about those yet. It can't, as they haven't landed, as building this code blocks Rust's CI but the expected-to-be-stabilized API can't be stabilized as long as this code requires that feature. Signed-off-by: Jubilee Young <[email protected]>
T-libs-api has consensus for stabilizing some of `feature(new_uninit)`, but not for `Box<MaybeUninit<T>>::write`. The replacement is trivial, so let's just do that, and RfL can simply move off the feature after it is stabilized. That will happen immediately after this unblocks Rust CI, as the relevant FCP has completed: rust-lang/rust#63291 (comment) This is required in advance of the stabilization because any remaining unstable API will be carved up into subfeatures as a direct result of stabilizing the majority of it. This code doesn't know about those yet. It can't, as they haven't landed, as building this code blocks Rust's CI but the expected-to-be-stabilized API can't be stabilized as long as this code requires that feature. Signed-off-by: Jubilee Young <[email protected]>
T-libs-api has consensus for stabilizing some of `feature(new_uninit)`, but not for `Box<MaybeUninit<T>>::write`. Instead, we can use `MaybeUninit<T>::write`, so Rust for Linux can drop the feature after stabilization. That will happen after merging, as the FCP has completed: rust-lang/rust#63291 (comment) This is required before stabilization because remaining-unstable API will be divided into new features. This code doesn't know about those yet. It can't: they haven't landed, as the relevant PR is blocked on rustc's CI testing Rust-for-Linux without this patch. Signed-off-by: Jubilee Young <[email protected]> Reviewed-by: Trevor Gross <[email protected]> Link: https://lore.kernel.org/r/[email protected]
…n-of-stabilization, r=<try> Partially stabilize `feature(new_uninit)` Finished comment period: rust-lang#63291 (comment) The following API has been stabilized from rust-lang#63291 ```rust impl<T> Box<T> { pub fn new_uninit() -> Box<MaybeUninit<T>> {…} } impl<T> Rc<T> { pub fn new_uninit() -> Rc<MaybeUninit<T>> {…} } impl<T> Arc<T> { pub fn new_uninit() -> Arc<MaybeUninit<T>> {…} } impl<T> Box<[T]> { pub fn new_uninit_slice(len: usize) -> Box<[MaybeUninit<T>]> {…} } impl<T> Rc<[T]> { pub fn new_uninit_slice(len: usize) -> Rc<[MaybeUninit<T>]> {…} } impl<T> Arc<[T]> { pub fn new_uninit_slice(len: usize) -> Arc<[MaybeUninit<T>]> {…} } impl<T> Box<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Box<T> {…} } impl<T> Box<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Box<[T]> {…} } impl<T> Rc<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Rc<T> {…} } impl<T> Rc<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Rc<[T]> {…} } impl<T> Arc<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Arc<T> {…} } impl<T> Arc<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Arc<[T]> {…} } ``` The remaining API is split between new issues - `new_zeroed_alloc`: rust-lang#129396 - `box_uninit_write`: rust-lang#129397 All relevant code is thus either stabilized or split out of that issue, so this closes rust-lang#63291 as, with the FCP concluded, that issue has served its purpose. try-job: x86_64-rust-for-linux
Upstream Rust's libs-api team has consensus for stabilizing some of `feature(new_uninit)`, but not for `Box<MaybeUninit<T>>::write`. Instead, we can use `MaybeUninit<T>::write`, so Rust for Linux can drop the feature after stabilization. That will happen after merging, as the FCP has completed [1]. This is required before stabilization because remaining-unstable API will be divided into new features. This code doesn't know about those yet. It can't: they haven't landed, as the relevant PR is blocked on rustc's CI testing Rust-for-Linux without this patch. [ The PR has landed [2], so we could conditionally enable the new unstable feature (`box_uninit_write` [3]) instead, but just for a single `unsafe` block it is probably not worth it. For the time being, I added it to the "nice to have" section of our unstable features list. - Miguel ] Link: rust-lang/rust#63291 (comment) [1] Link: rust-lang/rust#129416 [2] Link: rust-lang/rust#129397 [3] Signed-off-by: Jubilee Young <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Reviewed-by: Trevor Gross <[email protected]> [ Reworded slightly. - Miguel ] Signed-off-by: Miguel Ojeda <[email protected]>
Upstream Rust's libs-api team has consensus for stabilizing some of `feature(new_uninit)`, but not for `Box<MaybeUninit<T>>::write`. Instead, we can use `MaybeUninit<T>::write`, so Rust for Linux can drop the feature after stabilization. That will happen after merging, as the FCP has completed [1]. This is required before stabilization because remaining-unstable API will be divided into new features. This code doesn't know about those yet. It can't: they haven't landed, as the relevant PR is blocked on rustc's CI testing Rust-for-Linux without this patch. [ The PR has landed [2] and will be released in Rust 1.82.0 (expected on 2024-10-17), so we could conditionally enable the new unstable feature (`box_uninit_write` [3]) instead, but just for a single `unsafe` block it is probably not worth it. For the time being, I added it to the "nice to have" section of our unstable features list. - Miguel ] Link: rust-lang/rust#63291 (comment) [1] Link: rust-lang/rust#129416 [2] Link: rust-lang/rust#129397 [3] Signed-off-by: Jubilee Young <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Reviewed-by: Trevor Gross <[email protected]> [ Reworded slightly. - Miguel ] Signed-off-by: Miguel Ojeda <[email protected]>
…ion-of-stabilization, r=dtolnay Partially stabilize `feature(new_uninit)` Finished comment period: rust-lang#63291 (comment) The following API has been stabilized from rust-lang#63291 ```rust impl<T> Box<T> { pub fn new_uninit() -> Box<MaybeUninit<T>> {…} } impl<T> Rc<T> { pub fn new_uninit() -> Rc<MaybeUninit<T>> {…} } impl<T> Arc<T> { pub fn new_uninit() -> Arc<MaybeUninit<T>> {…} } impl<T> Box<[T]> { pub fn new_uninit_slice(len: usize) -> Box<[MaybeUninit<T>]> {…} } impl<T> Rc<[T]> { pub fn new_uninit_slice(len: usize) -> Rc<[MaybeUninit<T>]> {…} } impl<T> Arc<[T]> { pub fn new_uninit_slice(len: usize) -> Arc<[MaybeUninit<T>]> {…} } impl<T> Box<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Box<T> {…} } impl<T> Box<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Box<[T]> {…} } impl<T> Rc<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Rc<T> {…} } impl<T> Rc<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Rc<[T]> {…} } impl<T> Arc<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Arc<T> {…} } impl<T> Arc<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Arc<[T]> {…} } ``` The remaining API is split between new issues - `new_zeroed_alloc`: rust-lang#129396 - `box_uninit_write`: rust-lang#129397 All relevant code is thus either stabilized or split out of that issue, so this closes rust-lang#63291 as, with the FCP concluded, that issue has served its purpose. try-job: x86_64-rust-for-linux
…ion-of-stabilization, r=dtolnay,joboet Partially stabilize `feature(new_uninit)` Finished comment period: rust-lang#63291 (comment) The following API has been stabilized from rust-lang#63291 ```rust impl<T> Box<T> { pub fn new_uninit() -> Box<MaybeUninit<T>> {…} } impl<T> Rc<T> { pub fn new_uninit() -> Rc<MaybeUninit<T>> {…} } impl<T> Arc<T> { pub fn new_uninit() -> Arc<MaybeUninit<T>> {…} } impl<T> Box<[T]> { pub fn new_uninit_slice(len: usize) -> Box<[MaybeUninit<T>]> {…} } impl<T> Rc<[T]> { pub fn new_uninit_slice(len: usize) -> Rc<[MaybeUninit<T>]> {…} } impl<T> Arc<[T]> { pub fn new_uninit_slice(len: usize) -> Arc<[MaybeUninit<T>]> {…} } impl<T> Box<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Box<T> {…} } impl<T> Box<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Box<[T]> {…} } impl<T> Rc<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Rc<T> {…} } impl<T> Rc<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Rc<[T]> {…} } impl<T> Arc<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Arc<T> {…} } impl<T> Arc<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Arc<[T]> {…} } ``` The remaining API is split between new issues - `new_zeroed_alloc`: rust-lang#129396 - `box_uninit_write`: rust-lang#129397 All relevant code is thus either stabilized or split out of that issue, so this closes rust-lang#63291 as, with the FCP concluded, that issue has served its purpose. try-job: x86_64-rust-for-linux
Rollup merge of rust-lang#129401 - workingjubilee:partial-initialization-of-stabilization, r=dtolnay,joboet Partially stabilize `feature(new_uninit)` Finished comment period: rust-lang#63291 (comment) The following API has been stabilized from rust-lang#63291 ```rust impl<T> Box<T> { pub fn new_uninit() -> Box<MaybeUninit<T>> {…} } impl<T> Rc<T> { pub fn new_uninit() -> Rc<MaybeUninit<T>> {…} } impl<T> Arc<T> { pub fn new_uninit() -> Arc<MaybeUninit<T>> {…} } impl<T> Box<[T]> { pub fn new_uninit_slice(len: usize) -> Box<[MaybeUninit<T>]> {…} } impl<T> Rc<[T]> { pub fn new_uninit_slice(len: usize) -> Rc<[MaybeUninit<T>]> {…} } impl<T> Arc<[T]> { pub fn new_uninit_slice(len: usize) -> Arc<[MaybeUninit<T>]> {…} } impl<T> Box<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Box<T> {…} } impl<T> Box<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Box<[T]> {…} } impl<T> Rc<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Rc<T> {…} } impl<T> Rc<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Rc<[T]> {…} } impl<T> Arc<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Arc<T> {…} } impl<T> Arc<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Arc<[T]> {…} } ``` The remaining API is split between new issues - `new_zeroed_alloc`: rust-lang#129396 - `box_uninit_write`: rust-lang#129397 All relevant code is thus either stabilized or split out of that issue, so this closes rust-lang#63291 as, with the FCP concluded, that issue has served its purpose. try-job: x86_64-rust-for-linux
…abilization, r=dtolnay,joboet Partially stabilize `feature(new_uninit)` Finished comment period: rust-lang/rust#63291 (comment) The following API has been stabilized from rust-lang/rust#63291 ```rust impl<T> Box<T> { pub fn new_uninit() -> Box<MaybeUninit<T>> {…} } impl<T> Rc<T> { pub fn new_uninit() -> Rc<MaybeUninit<T>> {…} } impl<T> Arc<T> { pub fn new_uninit() -> Arc<MaybeUninit<T>> {…} } impl<T> Box<[T]> { pub fn new_uninit_slice(len: usize) -> Box<[MaybeUninit<T>]> {…} } impl<T> Rc<[T]> { pub fn new_uninit_slice(len: usize) -> Rc<[MaybeUninit<T>]> {…} } impl<T> Arc<[T]> { pub fn new_uninit_slice(len: usize) -> Arc<[MaybeUninit<T>]> {…} } impl<T> Box<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Box<T> {…} } impl<T> Box<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Box<[T]> {…} } impl<T> Rc<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Rc<T> {…} } impl<T> Rc<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Rc<[T]> {…} } impl<T> Arc<MaybeUninit<T>> { pub unsafe fn assume_init(self) -> Arc<T> {…} } impl<T> Arc<[MaybeUninit<T>]> { pub unsafe fn assume_init(self) -> Arc<[T]> {…} } ``` The remaining API is split between new issues - `new_zeroed_alloc`: rust-lang/rust#129396 - `box_uninit_write`: rust-lang/rust#129397 All relevant code is thus either stabilized or split out of that issue, so this closes #63291 as, with the FCP concluded, that issue has served its purpose. try-job: x86_64-rust-for-linux
Like commit 0903b9e ("rust: alloc: eschew `Box<MaybeUninit<T>>::write`"), but for the new `rbtree` code. That is, `feature(new_uninit)` [1] got partially stabilized [2] for Rust 1.82.0 (expected to be released on 2024-10-17), but it did not include `Box<MaybeUninit<T>>::write`, which got split into `feature(box_uninit_write)` [3]. To avoid relying on a new unstable feature, rewrite the `write` + `assume_init` pair manually. Link: rust-lang/rust#63291 [1] Link: rust-lang/rust#129401 [2] Link: rust-lang/rust#129397 [3] Signed-off-by: Miguel Ojeda <[email protected]>
Like commit 0903b9e ("rust: alloc: eschew `Box<MaybeUninit<T>>::write`"), but for the new `rbtree` and `alloc` code. That is, `feature(new_uninit)` [1] got partially stabilized [2] for Rust 1.82.0 (expected to be released on 2024-10-17), but it did not include `Box<MaybeUninit<T>>::write`, which got split into `feature(box_uninit_write)` [3]. To avoid relying on a new unstable feature, rewrite the `write` + `assume_init` pair manually. Link: rust-lang/rust#63291 [1] Link: rust-lang/rust#129401 [2] Link: rust-lang/rust#129397 [3] Signed-off-by: Miguel Ojeda <[email protected]>
Like commit 0903b9e ("rust: alloc: eschew `Box<MaybeUninit<T>>::write`"), but for the new `rbtree` and `alloc` code. That is, `feature(new_uninit)` [1] got partially stabilized [2] for Rust 1.82.0 (expected to be released on 2024-10-17), but it did not include `Box<MaybeUninit<T>>::write`, which got split into `feature(box_uninit_write)` [3]. To avoid relying on a new unstable feature, rewrite the `write` + `assume_init` pair manually. Link: rust-lang/rust#63291 [1] Link: rust-lang/rust#129401 [2] Link: rust-lang/rust#129397 [3] Signed-off-by: Miguel Ojeda <[email protected]>
Like commit 0903b9e ("rust: alloc: eschew `Box<MaybeUninit<T>>::write`"), but for the new `rbtree` and `alloc` code. That is, `feature(new_uninit)` [1] got partially stabilized [2] for Rust 1.82.0 (expected to be released on 2024-10-17), but it did not include `Box<MaybeUninit<T>>::write`, which got split into `feature(box_uninit_write)` [3]. To avoid relying on a new unstable feature, rewrite the `write` + `assume_init` pair manually. Link: rust-lang/rust#63291 [1] Link: rust-lang/rust#129401 [2] Link: rust-lang/rust#129397 [3] Signed-off-by: Miguel Ojeda <[email protected]>
Like commit 0903b9e ("rust: alloc: eschew `Box<MaybeUninit<T>>::write`"), but for the new `rbtree` and `alloc` code. That is, `feature(new_uninit)` [1] got partially stabilized [2] for Rust 1.82.0 (expected to be released on 2024-10-17), but it did not include `Box<MaybeUninit<T>>::write`, which got split into `feature(box_uninit_write)` [3]. To avoid relying on a new unstable feature, rewrite the `write` + `assume_init` pair manually. Link: rust-lang/rust#63291 [1] Link: rust-lang/rust#129401 [2] Link: rust-lang/rust#129397 [3] Signed-off-by: Miguel Ojeda <[email protected]>
Like commit 0903b9e ("rust: alloc: eschew `Box<MaybeUninit<T>>::write`"), but for the new `rbtree` and `alloc` code. That is, `feature(new_uninit)` [1] got partially stabilized [2] for Rust 1.82.0 (expected to be released on 2024-10-17), but it did not include `Box<MaybeUninit<T>>::write`, which got split into `feature(box_uninit_write)` [3]. To avoid relying on a new unstable feature, rewrite the `write` + `assume_init` pair manually. Link: rust-lang/rust#63291 [1] Link: rust-lang/rust#129401 [2] Link: rust-lang/rust#129397 [3] Signed-off-by: Miguel Ojeda <[email protected]>
Like commit 0903b9e ("rust: alloc: eschew `Box<MaybeUninit<T>>::write`"), but for the new `rbtree` and `alloc` code. That is, `feature(new_uninit)` [1] got partially stabilized [2] for Rust 1.82.0 (expected to be released on 2024-10-17), but it did not include `Box<MaybeUninit<T>>::write`, which got split into `feature(box_uninit_write)` [3]. To avoid relying on a new unstable feature, rewrite the `write` + `assume_init` pair manually. Link: rust-lang/rust#63291 [1] Link: rust-lang/rust#129401 [2] Link: rust-lang/rust#129397 [3] Reviewed-by: Alice Ryhl <[email protected]> Reviewed-by: Matt Gilbride <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Miguel Ojeda <[email protected]>
Upstream Rust's libs-api team has consensus for stabilizing some of `feature(new_uninit)`, but not for `Box<MaybeUninit<T>>::write`. Instead, we can use `MaybeUninit<T>::write`, so Rust for Linux can drop the feature after stabilization. That will happen after merging, as the FCP has completed [1]. This is required before stabilization because remaining-unstable API will be divided into new features. This code doesn't know about those yet. It can't: they haven't landed, as the relevant PR is blocked on rustc's CI testing Rust-for-Linux without this patch. [ The PR has landed [2] and will be released in Rust 1.82.0 (expected on 2024-10-17), so we could conditionally enable the new unstable feature (`box_uninit_write` [3]) instead, but just for a single `unsafe` block it is probably not worth it. For the time being, I added it to the "nice to have" section of our unstable features list. - Miguel ] Link: rust-lang/rust#63291 (comment) [1] Link: rust-lang/rust#129416 [2] Link: rust-lang/rust#129397 [3] Signed-off-by: Jubilee Young <[email protected]> Reviewed-by: Alice Ryhl <[email protected]> Reviewed-by: Trevor Gross <[email protected]> [ Reworded slightly. - Miguel ] Signed-off-by: Miguel Ojeda <[email protected]>
Assigning
MaybeUninit::<Foo>::uninit()
to a local variable is usually free, even whensize_of::<Foo>()
is large. However, passing it for example toArc::new
causes at least one copy (from the stack to the newly allocated heap memory) even though there is no meaningful data. It is theoretically possible that a Sufficiently Advanced Compiler could optimize this copy away, but this is reportedly unlikely to happen soon in LLVM.This issue tracks constructors for containers (
Box
,Rc
,Arc
) ofMaybeUninit<T>
or[MaybeUninit<T>]
that do not initialized the data, and unsafe conversions to the known-initialized types (withoutMaybeUninit
). The constructors are guaranteed not to make unnecessary copies.PR #62451 adds:
PR #66128 adds:
Unresolved question:
Box<MaybeUninit<T>>
might “belong” more as an associated function of that same type, rather thanBox<T>
. (And similarly for other constructors.) However this would make a call likeBox::<u32>::new_uninit()
becomesBox::<MaybeUnint<u32>>::new_uninit()
which feels unnecessarily verbose. I suspect that this turbofish will be needed in a lot of cases to appease type inference.The text was updated successfully, but these errors were encountered: