Skip to content
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

Rollup of 6 pull requests #130378

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/if_let_rescope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ declare_lint! {
/// ### Example
///
/// ```rust,edition2021
/// #![feature(if_let_rescope)]
/// #![cfg_attr(not(bootstrap), feature(if_let_rescope))] // Simplify this in bootstrap bump.
/// #![warn(if_let_rescope)]
/// #![allow(unused_variables)]
///
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint_defs/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1870,6 +1870,7 @@ declare_lint! {
/// ### Example
///
/// ```rust,compile_fail
/// # #[cfg_attr(bootstrap)] compile_error!(); // Remove this in bootstrap bump.
/// #![deny(elided_named_lifetimes)]
/// struct Foo;
/// impl Foo {
Expand Down
3 changes: 3 additions & 0 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -942,3 +942,6 @@
# Copy the linker, DLLs, and various libraries from MinGW into the Rust toolchain.
# Only applies when the host or target is pc-windows-gnu.
#include-mingw-linker = true

# Whether to vendor dependencies for the dist tarball.
#vendor = if "is a tarball source" || "is a git repository" { true } else { false }
223 changes: 223 additions & 0 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1060,6 +1060,59 @@ impl<T: ?Sized> Box<T> {
pub unsafe fn from_raw(raw: *mut T) -> Self {
unsafe { Self::from_raw_in(raw, Global) }
}

/// Constructs a box from a `NonNull` pointer.
///
/// After calling this function, the `NonNull` pointer is owned by
/// the resulting `Box`. Specifically, the `Box` destructor will call
/// the destructor of `T` and free the allocated memory. For this
/// to be safe, the memory must have been allocated in accordance
/// with the [memory layout] used by `Box` .
///
/// # Safety
///
/// This function is unsafe because improper use may lead to
/// memory problems. For example, a double-free may occur if the
/// function is called twice on the same `NonNull` pointer.
///
/// The safety conditions are described in the [memory layout] section.
///
/// # Examples
///
/// Recreate a `Box` which was previously converted to a `NonNull`
/// pointer using [`Box::into_non_null`]:
/// ```
/// #![feature(box_vec_non_null)]
///
/// let x = Box::new(5);
/// let non_null = Box::into_non_null(x);
/// let x = unsafe { Box::from_non_null(non_null) };
/// ```
/// Manually create a `Box` from scratch by using the global allocator:
/// ```
/// #![feature(box_vec_non_null)]
///
/// use std::alloc::{alloc, Layout};
/// use std::ptr::NonNull;
///
/// unsafe {
/// let non_null = NonNull::new(alloc(Layout::new::<i32>()).cast::<i32>())
/// .expect("allocation failed");
/// // In general .write is required to avoid attempting to destruct
/// // the (uninitialized) previous contents of `non_null`.
/// non_null.write(5);
/// let x = Box::from_non_null(non_null);
/// }
/// ```
///
/// [memory layout]: self#memory-layout
/// [`Layout`]: crate::Layout
#[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
#[inline]
#[must_use = "call `drop(Box::from_non_null(ptr))` if you intend to drop the `Box`"]
pub unsafe fn from_non_null(ptr: NonNull<T>) -> Self {
unsafe { Self::from_raw(ptr.as_ptr()) }
}
}

impl<T: ?Sized, A: Allocator> Box<T, A> {
Expand Down Expand Up @@ -1117,6 +1170,61 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
Box(unsafe { Unique::new_unchecked(raw) }, alloc)
}

/// Constructs a box from a `NonNull` pointer in the given allocator.
///
/// After calling this function, the `NonNull` pointer is owned by
/// the resulting `Box`. Specifically, the `Box` destructor will call
/// the destructor of `T` and free the allocated memory. For this
/// to be safe, the memory must have been allocated in accordance
/// with the [memory layout] used by `Box` .
///
/// # Safety
///
/// This function is unsafe because improper use may lead to
/// memory problems. For example, a double-free may occur if the
/// function is called twice on the same raw pointer.
///
///
/// # Examples
///
/// Recreate a `Box` which was previously converted to a `NonNull` pointer
/// using [`Box::into_non_null_with_allocator`]:
/// ```
/// #![feature(allocator_api, box_vec_non_null)]
///
/// use std::alloc::System;
///
/// let x = Box::new_in(5, System);
/// let (non_null, alloc) = Box::into_non_null_with_allocator(x);
/// let x = unsafe { Box::from_non_null_in(non_null, alloc) };
/// ```
/// Manually create a `Box` from scratch by using the system allocator:
/// ```
/// #![feature(allocator_api, box_vec_non_null, slice_ptr_get)]
///
/// use std::alloc::{Allocator, Layout, System};
///
/// unsafe {
/// let non_null = System.allocate(Layout::new::<i32>())?.cast::<i32>();
/// // In general .write is required to avoid attempting to destruct
/// // the (uninitialized) previous contents of `non_null`.
/// non_null.write(5);
/// let x = Box::from_non_null_in(non_null, System);
/// }
/// # Ok::<(), std::alloc::AllocError>(())
/// ```
///
/// [memory layout]: self#memory-layout
/// [`Layout`]: crate::Layout
#[unstable(feature = "allocator_api", issue = "32838")]
// #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
#[inline]
pub const unsafe fn from_non_null_in(raw: NonNull<T>, alloc: A) -> Self {
// SAFETY: guaranteed by the caller.
unsafe { Box::from_raw_in(raw.as_ptr(), alloc) }
}

/// Consumes the `Box`, returning a wrapped raw pointer.
///
/// The pointer will be properly aligned and non-null.
Expand Down Expand Up @@ -1172,6 +1280,66 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
unsafe { addr_of_mut!(*&mut *Self::into_raw_with_allocator(b).0) }
}

/// Consumes the `Box`, returning a wrapped `NonNull` pointer.
///
/// The pointer will be properly aligned.
///
/// After calling this function, the caller is responsible for the
/// memory previously managed by the `Box`. In particular, the
/// caller should properly destroy `T` and release the memory, taking
/// into account the [memory layout] used by `Box`. The easiest way to
/// do this is to convert the `NonNull` pointer back into a `Box` with the
/// [`Box::from_non_null`] function, allowing the `Box` destructor to
/// perform the cleanup.
///
/// Note: this is an associated function, which means that you have
/// to call it as `Box::into_non_null(b)` instead of `b.into_non_null()`.
/// This is so that there is no conflict with a method on the inner type.
///
/// # Examples
/// Converting the `NonNull` pointer back into a `Box` with [`Box::from_non_null`]
/// for automatic cleanup:
/// ```
/// #![feature(box_vec_non_null)]
///
/// let x = Box::new(String::from("Hello"));
/// let non_null = Box::into_non_null(x);
/// let x = unsafe { Box::from_non_null(non_null) };
/// ```
/// Manual cleanup by explicitly running the destructor and deallocating
/// the memory:
/// ```
/// #![feature(box_vec_non_null)]
///
/// use std::alloc::{dealloc, Layout};
///
/// let x = Box::new(String::from("Hello"));
/// let non_null = Box::into_non_null(x);
/// unsafe {
/// non_null.drop_in_place();
/// dealloc(non_null.as_ptr().cast::<u8>(), Layout::new::<String>());
/// }
/// ```
/// Note: This is equivalent to the following:
/// ```
/// #![feature(box_vec_non_null)]
///
/// let x = Box::new(String::from("Hello"));
/// let non_null = Box::into_non_null(x);
/// unsafe {
/// drop(Box::from_non_null(non_null));
/// }
/// ```
///
/// [memory layout]: self#memory-layout
#[must_use = "losing the pointer will leak memory"]
#[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
#[inline]
pub fn into_non_null(b: Self) -> NonNull<T> {
// SAFETY: `Box` is guaranteed to be non-null.
unsafe { NonNull::new_unchecked(Self::into_raw(b)) }
}

/// Consumes the `Box`, returning a wrapped raw pointer and the allocator.
///
/// The pointer will be properly aligned and non-null.
Expand Down Expand Up @@ -1233,6 +1401,61 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
(ptr, alloc)
}

/// Consumes the `Box`, returning a wrapped `NonNull` pointer and the allocator.
///
/// The pointer will be properly aligned.
///
/// After calling this function, the caller is responsible for the
/// memory previously managed by the `Box`. In particular, the
/// caller should properly destroy `T` and release the memory, taking
/// into account the [memory layout] used by `Box`. The easiest way to
/// do this is to convert the `NonNull` pointer back into a `Box` with the
/// [`Box::from_non_null_in`] function, allowing the `Box` destructor to
/// perform the cleanup.
///
/// Note: this is an associated function, which means that you have
/// to call it as `Box::into_non_null_with_allocator(b)` instead of
/// `b.into_non_null_with_allocator()`. This is so that there is no
/// conflict with a method on the inner type.
///
/// # Examples
/// Converting the `NonNull` pointer back into a `Box` with
/// [`Box::from_non_null_in`] for automatic cleanup:
/// ```
/// #![feature(allocator_api, box_vec_non_null)]
///
/// use std::alloc::System;
///
/// let x = Box::new_in(String::from("Hello"), System);
/// let (non_null, alloc) = Box::into_non_null_with_allocator(x);
/// let x = unsafe { Box::from_non_null_in(non_null, alloc) };
/// ```
/// Manual cleanup by explicitly running the destructor and deallocating
/// the memory:
/// ```
/// #![feature(allocator_api, box_vec_non_null)]
///
/// use std::alloc::{Allocator, Layout, System};
///
/// let x = Box::new_in(String::from("Hello"), System);
/// let (non_null, alloc) = Box::into_non_null_with_allocator(x);
/// unsafe {
/// non_null.drop_in_place();
/// alloc.deallocate(non_null.cast::<u8>(), Layout::new::<String>());
/// }
/// ```
///
/// [memory layout]: self#memory-layout
#[must_use = "losing the pointer will leak memory"]
#[unstable(feature = "allocator_api", issue = "32838")]
// #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
#[inline]
pub fn into_non_null_with_allocator(b: Self) -> (NonNull<T>, A) {
let (ptr, alloc) = Box::into_raw_with_allocator(b);
// SAFETY: `Box` is guaranteed to be non-null.
unsafe { (NonNull::new_unchecked(ptr), alloc) }
}

#[unstable(
feature = "ptr_internals",
issue = "none",
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/vec/in_place_collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ where

mem::forget(dst_guard);

let vec = unsafe { Vec::from_nonnull(dst_buf, len, dst_cap) };
let vec = unsafe { Vec::from_parts(dst_buf, len, dst_cap) };

vec
}
Expand Down
Loading
Loading