Skip to content

Commit 2c1bd02

Browse files
author
The Miri Cronjob Bot
committed
Merge from rustc
2 parents f30a0ad + ee67105 commit 2c1bd02

File tree

20 files changed

+648
-48
lines changed

20 files changed

+648
-48
lines changed

alloc/src/boxed.rs

+223
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,59 @@ impl<T: ?Sized> Box<T> {
10601060
pub unsafe fn from_raw(raw: *mut T) -> Self {
10611061
unsafe { Self::from_raw_in(raw, Global) }
10621062
}
1063+
1064+
/// Constructs a box from a `NonNull` pointer.
1065+
///
1066+
/// After calling this function, the `NonNull` pointer is owned by
1067+
/// the resulting `Box`. Specifically, the `Box` destructor will call
1068+
/// the destructor of `T` and free the allocated memory. For this
1069+
/// to be safe, the memory must have been allocated in accordance
1070+
/// with the [memory layout] used by `Box` .
1071+
///
1072+
/// # Safety
1073+
///
1074+
/// This function is unsafe because improper use may lead to
1075+
/// memory problems. For example, a double-free may occur if the
1076+
/// function is called twice on the same `NonNull` pointer.
1077+
///
1078+
/// The safety conditions are described in the [memory layout] section.
1079+
///
1080+
/// # Examples
1081+
///
1082+
/// Recreate a `Box` which was previously converted to a `NonNull`
1083+
/// pointer using [`Box::into_non_null`]:
1084+
/// ```
1085+
/// #![feature(box_vec_non_null)]
1086+
///
1087+
/// let x = Box::new(5);
1088+
/// let non_null = Box::into_non_null(x);
1089+
/// let x = unsafe { Box::from_non_null(non_null) };
1090+
/// ```
1091+
/// Manually create a `Box` from scratch by using the global allocator:
1092+
/// ```
1093+
/// #![feature(box_vec_non_null)]
1094+
///
1095+
/// use std::alloc::{alloc, Layout};
1096+
/// use std::ptr::NonNull;
1097+
///
1098+
/// unsafe {
1099+
/// let non_null = NonNull::new(alloc(Layout::new::<i32>()).cast::<i32>())
1100+
/// .expect("allocation failed");
1101+
/// // In general .write is required to avoid attempting to destruct
1102+
/// // the (uninitialized) previous contents of `non_null`.
1103+
/// non_null.write(5);
1104+
/// let x = Box::from_non_null(non_null);
1105+
/// }
1106+
/// ```
1107+
///
1108+
/// [memory layout]: self#memory-layout
1109+
/// [`Layout`]: crate::Layout
1110+
#[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
1111+
#[inline]
1112+
#[must_use = "call `drop(Box::from_non_null(ptr))` if you intend to drop the `Box`"]
1113+
pub unsafe fn from_non_null(ptr: NonNull<T>) -> Self {
1114+
unsafe { Self::from_raw(ptr.as_ptr()) }
1115+
}
10631116
}
10641117

10651118
impl<T: ?Sized, A: Allocator> Box<T, A> {
@@ -1117,6 +1170,61 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
11171170
Box(unsafe { Unique::new_unchecked(raw) }, alloc)
11181171
}
11191172

1173+
/// Constructs a box from a `NonNull` pointer in the given allocator.
1174+
///
1175+
/// After calling this function, the `NonNull` pointer is owned by
1176+
/// the resulting `Box`. Specifically, the `Box` destructor will call
1177+
/// the destructor of `T` and free the allocated memory. For this
1178+
/// to be safe, the memory must have been allocated in accordance
1179+
/// with the [memory layout] used by `Box` .
1180+
///
1181+
/// # Safety
1182+
///
1183+
/// This function is unsafe because improper use may lead to
1184+
/// memory problems. For example, a double-free may occur if the
1185+
/// function is called twice on the same raw pointer.
1186+
///
1187+
///
1188+
/// # Examples
1189+
///
1190+
/// Recreate a `Box` which was previously converted to a `NonNull` pointer
1191+
/// using [`Box::into_non_null_with_allocator`]:
1192+
/// ```
1193+
/// #![feature(allocator_api, box_vec_non_null)]
1194+
///
1195+
/// use std::alloc::System;
1196+
///
1197+
/// let x = Box::new_in(5, System);
1198+
/// let (non_null, alloc) = Box::into_non_null_with_allocator(x);
1199+
/// let x = unsafe { Box::from_non_null_in(non_null, alloc) };
1200+
/// ```
1201+
/// Manually create a `Box` from scratch by using the system allocator:
1202+
/// ```
1203+
/// #![feature(allocator_api, box_vec_non_null, slice_ptr_get)]
1204+
///
1205+
/// use std::alloc::{Allocator, Layout, System};
1206+
///
1207+
/// unsafe {
1208+
/// let non_null = System.allocate(Layout::new::<i32>())?.cast::<i32>();
1209+
/// // In general .write is required to avoid attempting to destruct
1210+
/// // the (uninitialized) previous contents of `non_null`.
1211+
/// non_null.write(5);
1212+
/// let x = Box::from_non_null_in(non_null, System);
1213+
/// }
1214+
/// # Ok::<(), std::alloc::AllocError>(())
1215+
/// ```
1216+
///
1217+
/// [memory layout]: self#memory-layout
1218+
/// [`Layout`]: crate::Layout
1219+
#[unstable(feature = "allocator_api", issue = "32838")]
1220+
// #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
1221+
#[rustc_const_unstable(feature = "const_box", issue = "92521")]
1222+
#[inline]
1223+
pub const unsafe fn from_non_null_in(raw: NonNull<T>, alloc: A) -> Self {
1224+
// SAFETY: guaranteed by the caller.
1225+
unsafe { Box::from_raw_in(raw.as_ptr(), alloc) }
1226+
}
1227+
11201228
/// Consumes the `Box`, returning a wrapped raw pointer.
11211229
///
11221230
/// The pointer will be properly aligned and non-null.
@@ -1172,6 +1280,66 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
11721280
unsafe { addr_of_mut!(*&mut *Self::into_raw_with_allocator(b).0) }
11731281
}
11741282

1283+
/// Consumes the `Box`, returning a wrapped `NonNull` pointer.
1284+
///
1285+
/// The pointer will be properly aligned.
1286+
///
1287+
/// After calling this function, the caller is responsible for the
1288+
/// memory previously managed by the `Box`. In particular, the
1289+
/// caller should properly destroy `T` and release the memory, taking
1290+
/// into account the [memory layout] used by `Box`. The easiest way to
1291+
/// do this is to convert the `NonNull` pointer back into a `Box` with the
1292+
/// [`Box::from_non_null`] function, allowing the `Box` destructor to
1293+
/// perform the cleanup.
1294+
///
1295+
/// Note: this is an associated function, which means that you have
1296+
/// to call it as `Box::into_non_null(b)` instead of `b.into_non_null()`.
1297+
/// This is so that there is no conflict with a method on the inner type.
1298+
///
1299+
/// # Examples
1300+
/// Converting the `NonNull` pointer back into a `Box` with [`Box::from_non_null`]
1301+
/// for automatic cleanup:
1302+
/// ```
1303+
/// #![feature(box_vec_non_null)]
1304+
///
1305+
/// let x = Box::new(String::from("Hello"));
1306+
/// let non_null = Box::into_non_null(x);
1307+
/// let x = unsafe { Box::from_non_null(non_null) };
1308+
/// ```
1309+
/// Manual cleanup by explicitly running the destructor and deallocating
1310+
/// the memory:
1311+
/// ```
1312+
/// #![feature(box_vec_non_null)]
1313+
///
1314+
/// use std::alloc::{dealloc, Layout};
1315+
///
1316+
/// let x = Box::new(String::from("Hello"));
1317+
/// let non_null = Box::into_non_null(x);
1318+
/// unsafe {
1319+
/// non_null.drop_in_place();
1320+
/// dealloc(non_null.as_ptr().cast::<u8>(), Layout::new::<String>());
1321+
/// }
1322+
/// ```
1323+
/// Note: This is equivalent to the following:
1324+
/// ```
1325+
/// #![feature(box_vec_non_null)]
1326+
///
1327+
/// let x = Box::new(String::from("Hello"));
1328+
/// let non_null = Box::into_non_null(x);
1329+
/// unsafe {
1330+
/// drop(Box::from_non_null(non_null));
1331+
/// }
1332+
/// ```
1333+
///
1334+
/// [memory layout]: self#memory-layout
1335+
#[must_use = "losing the pointer will leak memory"]
1336+
#[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
1337+
#[inline]
1338+
pub fn into_non_null(b: Self) -> NonNull<T> {
1339+
// SAFETY: `Box` is guaranteed to be non-null.
1340+
unsafe { NonNull::new_unchecked(Self::into_raw(b)) }
1341+
}
1342+
11751343
/// Consumes the `Box`, returning a wrapped raw pointer and the allocator.
11761344
///
11771345
/// The pointer will be properly aligned and non-null.
@@ -1233,6 +1401,61 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
12331401
(ptr, alloc)
12341402
}
12351403

1404+
/// Consumes the `Box`, returning a wrapped `NonNull` pointer and the allocator.
1405+
///
1406+
/// The pointer will be properly aligned.
1407+
///
1408+
/// After calling this function, the caller is responsible for the
1409+
/// memory previously managed by the `Box`. In particular, the
1410+
/// caller should properly destroy `T` and release the memory, taking
1411+
/// into account the [memory layout] used by `Box`. The easiest way to
1412+
/// do this is to convert the `NonNull` pointer back into a `Box` with the
1413+
/// [`Box::from_non_null_in`] function, allowing the `Box` destructor to
1414+
/// perform the cleanup.
1415+
///
1416+
/// Note: this is an associated function, which means that you have
1417+
/// to call it as `Box::into_non_null_with_allocator(b)` instead of
1418+
/// `b.into_non_null_with_allocator()`. This is so that there is no
1419+
/// conflict with a method on the inner type.
1420+
///
1421+
/// # Examples
1422+
/// Converting the `NonNull` pointer back into a `Box` with
1423+
/// [`Box::from_non_null_in`] for automatic cleanup:
1424+
/// ```
1425+
/// #![feature(allocator_api, box_vec_non_null)]
1426+
///
1427+
/// use std::alloc::System;
1428+
///
1429+
/// let x = Box::new_in(String::from("Hello"), System);
1430+
/// let (non_null, alloc) = Box::into_non_null_with_allocator(x);
1431+
/// let x = unsafe { Box::from_non_null_in(non_null, alloc) };
1432+
/// ```
1433+
/// Manual cleanup by explicitly running the destructor and deallocating
1434+
/// the memory:
1435+
/// ```
1436+
/// #![feature(allocator_api, box_vec_non_null)]
1437+
///
1438+
/// use std::alloc::{Allocator, Layout, System};
1439+
///
1440+
/// let x = Box::new_in(String::from("Hello"), System);
1441+
/// let (non_null, alloc) = Box::into_non_null_with_allocator(x);
1442+
/// unsafe {
1443+
/// non_null.drop_in_place();
1444+
/// alloc.deallocate(non_null.cast::<u8>(), Layout::new::<String>());
1445+
/// }
1446+
/// ```
1447+
///
1448+
/// [memory layout]: self#memory-layout
1449+
#[must_use = "losing the pointer will leak memory"]
1450+
#[unstable(feature = "allocator_api", issue = "32838")]
1451+
// #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
1452+
#[inline]
1453+
pub fn into_non_null_with_allocator(b: Self) -> (NonNull<T>, A) {
1454+
let (ptr, alloc) = Box::into_raw_with_allocator(b);
1455+
// SAFETY: `Box` is guaranteed to be non-null.
1456+
unsafe { (NonNull::new_unchecked(ptr), alloc) }
1457+
}
1458+
12361459
#[unstable(
12371460
feature = "ptr_internals",
12381461
issue = "none",

alloc/src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@
114114
#![feature(const_maybe_uninit_write)]
115115
#![feature(const_option)]
116116
#![feature(const_pin)]
117-
#![feature(const_refs_to_cell)]
118117
#![feature(const_size_of_val)]
119118
#![feature(core_intrinsics)]
120119
#![feature(deprecated_suggestion)]
@@ -164,13 +163,14 @@
164163
//
165164
// Language features:
166165
// tidy-alphabetical-start
166+
#![cfg_attr(bootstrap, feature(const_mut_refs))]
167+
#![cfg_attr(bootstrap, feature(const_refs_to_cell))]
167168
#![cfg_attr(not(test), feature(coroutine_trait))]
168169
#![cfg_attr(test, feature(panic_update_hook))]
169170
#![cfg_attr(test, feature(test))]
170171
#![feature(allocator_internals)]
171172
#![feature(allow_internal_unstable)]
172173
#![feature(cfg_sanitize)]
173-
#![feature(const_mut_refs)]
174174
#![feature(const_precise_live_drops)]
175175
#![feature(const_ptr_write)]
176176
#![feature(const_try)]

alloc/src/string.rs

+74
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,56 @@ impl String {
660660
Cow::Owned(res)
661661
}
662662

663+
/// Converts a [`Vec<u8>`] to a `String`, substituting invalid UTF-8
664+
/// sequences with replacement characters.
665+
///
666+
/// See [`from_utf8_lossy`] for more details.
667+
///
668+
/// [`from_utf8_lossy`]: String::from_utf8_lossy
669+
///
670+
/// Note that this function does not guarantee reuse of the original `Vec`
671+
/// allocation.
672+
///
673+
/// # Examples
674+
///
675+
/// Basic usage:
676+
///
677+
/// ```
678+
/// #![feature(string_from_utf8_lossy_owned)]
679+
/// // some bytes, in a vector
680+
/// let sparkle_heart = vec![240, 159, 146, 150];
681+
///
682+
/// let sparkle_heart = String::from_utf8_lossy_owned(sparkle_heart);
683+
///
684+
/// assert_eq!(String::from("💖"), sparkle_heart);
685+
/// ```
686+
///
687+
/// Incorrect bytes:
688+
///
689+
/// ```
690+
/// #![feature(string_from_utf8_lossy_owned)]
691+
/// // some invalid bytes
692+
/// let input: Vec<u8> = b"Hello \xF0\x90\x80World".into();
693+
/// let output = String::from_utf8_lossy_owned(input);
694+
///
695+
/// assert_eq!(String::from("Hello �World"), output);
696+
/// ```
697+
#[must_use]
698+
#[cfg(not(no_global_oom_handling))]
699+
#[unstable(feature = "string_from_utf8_lossy_owned", issue = "129436")]
700+
pub fn from_utf8_lossy_owned(v: Vec<u8>) -> String {
701+
if let Cow::Owned(string) = String::from_utf8_lossy(&v) {
702+
string
703+
} else {
704+
// SAFETY: `String::from_utf8_lossy`'s contract ensures that if
705+
// it returns a `Cow::Borrowed`, it is a valid UTF-8 string.
706+
// Otherwise, it returns a new allocation of an owned `String`, with
707+
// replacement characters for invalid sequences, which is returned
708+
// above.
709+
unsafe { String::from_utf8_unchecked(v) }
710+
}
711+
}
712+
663713
/// Decode a UTF-16–encoded vector `v` into a `String`, returning [`Err`]
664714
/// if `v` contains any invalid data.
665715
///
@@ -2010,6 +2060,30 @@ impl FromUtf8Error {
20102060
&self.bytes[..]
20112061
}
20122062

2063+
/// Converts the bytes into a `String` lossily, substituting invalid UTF-8
2064+
/// sequences with replacement characters.
2065+
///
2066+
/// See [`String::from_utf8_lossy`] for more details on replacement of
2067+
/// invalid sequences, and [`String::from_utf8_lossy_owned`] for the
2068+
/// `String` function which corresponds to this function.
2069+
///
2070+
/// # Examples
2071+
///
2072+
/// ```
2073+
/// #![feature(string_from_utf8_lossy_owned)]
2074+
/// // some invalid bytes
2075+
/// let input: Vec<u8> = b"Hello \xF0\x90\x80World".into();
2076+
/// let output = String::from_utf8(input).unwrap_or_else(|e| e.into_utf8_lossy());
2077+
///
2078+
/// assert_eq!(String::from("Hello �World"), output);
2079+
/// ```
2080+
#[must_use]
2081+
#[cfg(not(no_global_oom_handling))]
2082+
#[unstable(feature = "string_from_utf8_lossy_owned", issue = "129436")]
2083+
pub fn into_utf8_lossy(self) -> String {
2084+
String::from_utf8_lossy_owned(self.bytes)
2085+
}
2086+
20132087
/// Returns the bytes that were attempted to convert to a `String`.
20142088
///
20152089
/// This method is carefully constructed to avoid allocation. It will

alloc/src/vec/in_place_collect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ where
328328

329329
mem::forget(dst_guard);
330330

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

333333
vec
334334
}

0 commit comments

Comments
 (0)