Skip to content

Commit 73cd635

Browse files
committed
Auto merge of rust-lang#121142 - GuillaumeGomez:rollup-5qmksjw, r=GuillaumeGomez
Rollup of 8 pull requests Successful merges: - rust-lang#120449 (Document requirements for unsized {Rc,Arc}::from_raw) - rust-lang#120505 (Fix BTreeMap's Cursor::remove_{next,prev}) - rust-lang#120672 (std::thread update freebsd stack guard handling.) - rust-lang#121088 (Implicitly enable evex512 if avx512 is enabled) - rust-lang#121104 (Ignore unsized types when trying to determine the size of the original type) - rust-lang#121107 (Fix msg for verbose suggestions with confusable capitalization) - rust-lang#121113 (Continue compilation even if inherent impl checks fail) - rust-lang#121120 (Add `ErrorGuaranteed` to `ast::LitKind::Err`, `token::LitKind::Err`.) r? `@ghost` `@rustbot` modify labels: rollup
2 parents e7ef96e + f4c2acb commit 73cd635

File tree

6 files changed

+166
-34
lines changed

6 files changed

+166
-34
lines changed

alloc/src/collections/btree/map.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3247,9 +3247,15 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> {
32473247
#[unstable(feature = "btree_cursors", issue = "107540")]
32483248
pub fn remove_next(&mut self) -> Option<(K, V)> {
32493249
let current = self.current.take()?;
3250+
if current.reborrow().next_kv().is_err() {
3251+
self.current = Some(current);
3252+
return None;
3253+
}
32503254
let mut emptied_internal_root = false;
32513255
let (kv, pos) = current
32523256
.next_kv()
3257+
// This should be unwrap(), but that doesn't work because NodeRef
3258+
// doesn't implement Debug. The condition is checked above.
32533259
.ok()?
32543260
.remove_kv_tracking(|| emptied_internal_root = true, self.alloc.clone());
32553261
self.current = Some(pos);
@@ -3270,9 +3276,15 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> {
32703276
#[unstable(feature = "btree_cursors", issue = "107540")]
32713277
pub fn remove_prev(&mut self) -> Option<(K, V)> {
32723278
let current = self.current.take()?;
3279+
if current.reborrow().next_back_kv().is_err() {
3280+
self.current = Some(current);
3281+
return None;
3282+
}
32733283
let mut emptied_internal_root = false;
32743284
let (kv, pos) = current
32753285
.next_back_kv()
3286+
// This should be unwrap(), but that doesn't work because NodeRef
3287+
// doesn't implement Debug. The condition is checked above.
32763288
.ok()?
32773289
.remove_kv_tracking(|| emptied_internal_root = true, self.alloc.clone());
32783290
self.current = Some(pos);

alloc/src/rc.rs

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,12 +1184,19 @@ impl<T: ?Sized> Rc<T> {
11841184
/// Constructs an `Rc<T>` from a raw pointer.
11851185
///
11861186
/// The raw pointer must have been previously returned by a call to
1187-
/// [`Rc<U>::into_raw`][into_raw] where `U` must have the same size
1188-
/// and alignment as `T`. This is trivially true if `U` is `T`.
1189-
/// Note that if `U` is not `T` but has the same size and alignment, this is
1190-
/// basically like transmuting references of different types. See
1191-
/// [`mem::transmute`][transmute] for more information on what
1192-
/// restrictions apply in this case.
1187+
/// [`Rc<U>::into_raw`][into_raw] with the following requirements:
1188+
///
1189+
/// * If `U` is sized, it must have the same size and alignment as `T`. This
1190+
/// is trivially true if `U` is `T`.
1191+
/// * If `U` is unsized, its data pointer must have the same size and
1192+
/// alignment as `T`. This is trivially true if `Rc<U>` was constructed
1193+
/// through `Rc<T>` and then converted to `Rc<U>` through an [unsized
1194+
/// coercion].
1195+
///
1196+
/// Note that if `U` or `U`'s data pointer is not `T` but has the same size
1197+
/// and alignment, this is basically like transmuting references of
1198+
/// different types. See [`mem::transmute`][transmute] for more information
1199+
/// on what restrictions apply in this case.
11931200
///
11941201
/// The raw pointer must point to a block of memory allocated by the global allocator
11951202
///
@@ -1201,6 +1208,7 @@ impl<T: ?Sized> Rc<T> {
12011208
///
12021209
/// [into_raw]: Rc::into_raw
12031210
/// [transmute]: core::mem::transmute
1211+
/// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
12041212
///
12051213
/// # Examples
12061214
///
@@ -1220,6 +1228,20 @@ impl<T: ?Sized> Rc<T> {
12201228
///
12211229
/// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
12221230
/// ```
1231+
///
1232+
/// Convert a slice back into its original array:
1233+
///
1234+
/// ```
1235+
/// use std::rc::Rc;
1236+
///
1237+
/// let x: Rc<[u32]> = Rc::new([1, 2, 3]);
1238+
/// let x_ptr: *const [u32] = Rc::into_raw(x);
1239+
///
1240+
/// unsafe {
1241+
/// let x: Rc<[u32; 3]> = Rc::from_raw(x_ptr.cast::<[u32; 3]>());
1242+
/// assert_eq!(&*x, &[1, 2, 3]);
1243+
/// }
1244+
/// ```
12231245
#[inline]
12241246
#[stable(feature = "rc_raw", since = "1.17.0")]
12251247
pub unsafe fn from_raw(ptr: *const T) -> Self {
@@ -1344,13 +1366,20 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
13441366

13451367
/// Constructs an `Rc<T, A>` from a raw pointer in the provided allocator.
13461368
///
1347-
/// The raw pointer must have been previously returned by a call to
1348-
/// [`Rc<U, A>::into_raw`][into_raw] where `U` must have the same size
1349-
/// and alignment as `T`. This is trivially true if `U` is `T`.
1350-
/// Note that if `U` is not `T` but has the same size and alignment, this is
1351-
/// basically like transmuting references of different types. See
1352-
/// [`mem::transmute`] for more information on what
1353-
/// restrictions apply in this case.
1369+
/// The raw pointer must have been previously returned by a call to [`Rc<U,
1370+
/// A>::into_raw`][into_raw] with the following requirements:
1371+
///
1372+
/// * If `U` is sized, it must have the same size and alignment as `T`. This
1373+
/// is trivially true if `U` is `T`.
1374+
/// * If `U` is unsized, its data pointer must have the same size and
1375+
/// alignment as `T`. This is trivially true if `Rc<U>` was constructed
1376+
/// through `Rc<T>` and then converted to `Rc<U>` through an [unsized
1377+
/// coercion].
1378+
///
1379+
/// Note that if `U` or `U`'s data pointer is not `T` but has the same size
1380+
/// and alignment, this is basically like transmuting references of
1381+
/// different types. See [`mem::transmute`][transmute] for more information
1382+
/// on what restrictions apply in this case.
13541383
///
13551384
/// The raw pointer must point to a block of memory allocated by `alloc`
13561385
///
@@ -1361,6 +1390,8 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
13611390
/// even if the returned `Rc<T>` is never accessed.
13621391
///
13631392
/// [into_raw]: Rc::into_raw
1393+
/// [transmute]: core::mem::transmute
1394+
/// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
13641395
///
13651396
/// # Examples
13661397
///
@@ -1383,6 +1414,23 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
13831414
///
13841415
/// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
13851416
/// ```
1417+
///
1418+
/// Convert a slice back into its original array:
1419+
///
1420+
/// ```
1421+
/// #![feature(allocator_api)]
1422+
///
1423+
/// use std::rc::Rc;
1424+
/// use std::alloc::System;
1425+
///
1426+
/// let x: Rc<[u32], _> = Rc::new_in([1, 2, 3], System);
1427+
/// let x_ptr: *const [u32] = Rc::into_raw(x);
1428+
///
1429+
/// unsafe {
1430+
/// let x: Rc<[u32; 3], _> = Rc::from_raw_in(x_ptr.cast::<[u32; 3]>(), System);
1431+
/// assert_eq!(&*x, &[1, 2, 3]);
1432+
/// }
1433+
/// ```
13861434
#[unstable(feature = "allocator_api", issue = "32838")]
13871435
pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self {
13881436
let offset = unsafe { data_offset(ptr) };

alloc/src/sync.rs

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,12 +1333,19 @@ impl<T: ?Sized> Arc<T> {
13331333
/// Constructs an `Arc<T>` from a raw pointer.
13341334
///
13351335
/// The raw pointer must have been previously returned by a call to
1336-
/// [`Arc<U>::into_raw`][into_raw] where `U` must have the same size and
1337-
/// alignment as `T`. This is trivially true if `U` is `T`.
1338-
/// Note that if `U` is not `T` but has the same size and alignment, this is
1339-
/// basically like transmuting references of different types. See
1340-
/// [`mem::transmute`][transmute] for more information on what
1341-
/// restrictions apply in this case.
1336+
/// [`Arc<U>::into_raw`][into_raw] with the following requirements:
1337+
///
1338+
/// * If `U` is sized, it must have the same size and alignment as `T`. This
1339+
/// is trivially true if `U` is `T`.
1340+
/// * If `U` is unsized, its data pointer must have the same size and
1341+
/// alignment as `T`. This is trivially true if `Arc<U>` was constructed
1342+
/// through `Arc<T>` and then converted to `Arc<U>` through an [unsized
1343+
/// coercion].
1344+
///
1345+
/// Note that if `U` or `U`'s data pointer is not `T` but has the same size
1346+
/// and alignment, this is basically like transmuting references of
1347+
/// different types. See [`mem::transmute`][transmute] for more information
1348+
/// on what restrictions apply in this case.
13421349
///
13431350
/// The user of `from_raw` has to make sure a specific value of `T` is only
13441351
/// dropped once.
@@ -1348,6 +1355,7 @@ impl<T: ?Sized> Arc<T> {
13481355
///
13491356
/// [into_raw]: Arc::into_raw
13501357
/// [transmute]: core::mem::transmute
1358+
/// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
13511359
///
13521360
/// # Examples
13531361
///
@@ -1367,6 +1375,20 @@ impl<T: ?Sized> Arc<T> {
13671375
///
13681376
/// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
13691377
/// ```
1378+
///
1379+
/// Convert a slice back into its original array:
1380+
///
1381+
/// ```
1382+
/// use std::sync::Arc;
1383+
///
1384+
/// let x: Arc<[u32]> = Arc::new([1, 2, 3]);
1385+
/// let x_ptr: *const [u32] = Arc::into_raw(x);
1386+
///
1387+
/// unsafe {
1388+
/// let x: Arc<[u32; 3]> = Arc::from_raw(x_ptr.cast::<[u32; 3]>());
1389+
/// assert_eq!(&*x, &[1, 2, 3]);
1390+
/// }
1391+
/// ```
13701392
#[inline]
13711393
#[stable(feature = "rc_raw", since = "1.17.0")]
13721394
pub unsafe fn from_raw(ptr: *const T) -> Self {
@@ -1496,13 +1518,20 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
14961518

14971519
/// Constructs an `Arc<T, A>` from a raw pointer.
14981520
///
1499-
/// The raw pointer must have been previously returned by a call to
1500-
/// [`Arc<U, A>::into_raw`][into_raw] where `U` must have the same size and
1501-
/// alignment as `T`. This is trivially true if `U` is `T`.
1502-
/// Note that if `U` is not `T` but has the same size and alignment, this is
1503-
/// basically like transmuting references of different types. See
1504-
/// [`mem::transmute`] for more information on what
1505-
/// restrictions apply in this case.
1521+
/// The raw pointer must have been previously returned by a call to [`Arc<U,
1522+
/// A>::into_raw`][into_raw] with the following requirements:
1523+
///
1524+
/// * If `U` is sized, it must have the same size and alignment as `T`. This
1525+
/// is trivially true if `U` is `T`.
1526+
/// * If `U` is unsized, its data pointer must have the same size and
1527+
/// alignment as `T`. This is trivially true if `Arc<U>` was constructed
1528+
/// through `Arc<T>` and then converted to `Arc<U>` through an [unsized
1529+
/// coercion].
1530+
///
1531+
/// Note that if `U` or `U`'s data pointer is not `T` but has the same size
1532+
/// and alignment, this is basically like transmuting references of
1533+
/// different types. See [`mem::transmute`][transmute] for more information
1534+
/// on what restrictions apply in this case.
15061535
///
15071536
/// The raw pointer must point to a block of memory allocated by `alloc`
15081537
///
@@ -1513,6 +1542,8 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
15131542
/// even if the returned `Arc<T>` is never accessed.
15141543
///
15151544
/// [into_raw]: Arc::into_raw
1545+
/// [transmute]: core::mem::transmute
1546+
/// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
15161547
///
15171548
/// # Examples
15181549
///
@@ -1535,6 +1566,23 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
15351566
///
15361567
/// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
15371568
/// ```
1569+
///
1570+
/// Convert a slice back into its original array:
1571+
///
1572+
/// ```
1573+
/// #![feature(allocator_api)]
1574+
///
1575+
/// use std::sync::Arc;
1576+
/// use std::alloc::System;
1577+
///
1578+
/// let x: Arc<[u32], _> = Arc::new_in([1, 2, 3], System);
1579+
/// let x_ptr: *const [u32] = Arc::into_raw(x);
1580+
///
1581+
/// unsafe {
1582+
/// let x: Arc<[u32; 3], _> = Arc::from_raw_in(x_ptr.cast::<[u32; 3]>(), System);
1583+
/// assert_eq!(&*x, &[1, 2, 3]);
1584+
/// }
1585+
/// ```
15381586
#[inline]
15391587
#[unstable(feature = "allocator_api", issue = "32838")]
15401588
pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self {

proc_macro/src/bridge/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,11 @@ pub enum LitKind {
337337
ByteStrRaw(u8),
338338
CStr,
339339
CStrRaw(u8),
340-
Err,
340+
// This should have an `ErrorGuaranteed`, except that type isn't available
341+
// in this crate. (Imagine it is there.) Hence the `WithGuar` suffix. Must
342+
// only be constructed in `LitKind::from_internal`, where an
343+
// `ErrorGuaranteed` is available.
344+
ErrWithGuar,
341345
}
342346

343347
rpc_encode_decode!(
@@ -352,7 +356,7 @@ rpc_encode_decode!(
352356
ByteStrRaw(n),
353357
CStr,
354358
CStrRaw(n),
355-
Err,
359+
ErrWithGuar,
356360
}
357361
);
358362

proc_macro/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1451,7 +1451,7 @@ impl Literal {
14511451
f(&["cr", hashes, "\"", symbol, "\"", hashes, suffix])
14521452
}
14531453

1454-
bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::Err => {
1454+
bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::ErrWithGuar => {
14551455
f(&[symbol, suffix])
14561456
}
14571457
})

std/src/sys/pal/unix/thread.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -847,11 +847,31 @@ pub mod guard {
847847
let stackptr = get_stack_start_aligned()?;
848848
let guardaddr = stackptr.addr();
849849
// Technically the number of guard pages is tunable and controlled
850-
// by the security.bsd.stack_guard_page sysctl, but there are
851-
// few reasons to change it from the default. The default value has
852-
// been 1 ever since FreeBSD 11.1 and 10.4.
853-
const GUARD_PAGES: usize = 1;
854-
let guard = guardaddr..guardaddr + GUARD_PAGES * page_size;
850+
// by the security.bsd.stack_guard_page sysctl.
851+
// By default it is 1, checking once is enough since it is
852+
// a boot time config value.
853+
static LOCK: crate::sync::OnceLock<usize> = crate::sync::OnceLock::new();
854+
let guard = guardaddr
855+
..guardaddr
856+
+ *LOCK.get_or_init(|| {
857+
use crate::sys::weak::dlsym;
858+
dlsym!(fn sysctlbyname(*const libc::c_char, *mut libc::c_void, *mut libc::size_t, *const libc::c_void, libc::size_t) -> libc::c_int);
859+
let mut guard: usize = 0;
860+
let mut size = crate::mem::size_of_val(&guard);
861+
let oid = crate::ffi::CStr::from_bytes_with_nul(
862+
b"security.bsd.stack_guard_page\0",
863+
)
864+
.unwrap();
865+
match sysctlbyname.get() {
866+
Some(fcn) => {
867+
if fcn(oid.as_ptr(), &mut guard as *mut _ as *mut _, &mut size as *mut _ as *mut _, crate::ptr::null_mut(), 0) == 0 {
868+
return guard;
869+
}
870+
return 1;
871+
},
872+
_ => { return 1; }
873+
}
874+
}) * page_size;
855875
Some(guard)
856876
} else if cfg!(target_os = "openbsd") {
857877
// OpenBSD stack already includes a guard page, and stack is

0 commit comments

Comments
 (0)