From a300df74d13a8fd0e3bf4f13ba31f79b7b5dba44 Mon Sep 17 00:00:00 2001 From: Georgii Rylov Date: Mon, 5 Aug 2024 09:48:26 +0100 Subject: [PATCH 1/4] WASI fixing unsafe_op_in_unsafe_fn for std::{os, sys} --- std/src/os/wasi/fs.rs | 1 - std/src/os/wasi/mod.rs | 2 +- std/src/os/wasip2/mod.rs | 1 + std/src/sys/pal/wasi/args.rs | 2 +- std/src/sys/pal/wasi/env.rs | 2 ++ std/src/sys/pal/wasi/fd.rs | 2 +- std/src/sys/pal/wasi/fs.rs | 2 +- std/src/sys/pal/wasi/helpers.rs | 2 ++ std/src/sys/pal/wasi/io.rs | 2 +- std/src/sys/pal/wasi/net.rs | 2 +- std/src/sys/pal/wasi/os.rs | 2 +- std/src/sys/pal/wasi/stdio.rs | 2 +- std/src/sys/pal/wasi/thread.rs | 18 ++++++++++-------- std/src/sys/pal/wasi/time.rs | 2 +- 14 files changed, 24 insertions(+), 18 deletions(-) diff --git a/std/src/os/wasi/fs.rs b/std/src/os/wasi/fs.rs index a58ca543d677..9ec3e387e2ba 100644 --- a/std/src/os/wasi/fs.rs +++ b/std/src/os/wasi/fs.rs @@ -2,7 +2,6 @@ //! //! [`std::fs`]: crate::fs -#![deny(unsafe_op_in_unsafe_fn)] #![unstable(feature = "wasi_ext", issue = "71213")] // Used for `File::read` on intra-doc links diff --git a/std/src/os/wasi/mod.rs b/std/src/os/wasi/mod.rs index e36b93e60ea1..33b50c9e53b8 100644 --- a/std/src/os/wasi/mod.rs +++ b/std/src/os/wasi/mod.rs @@ -30,7 +30,7 @@ #![cfg_attr(not(target_env = "p2"), stable(feature = "rust1", since = "1.0.0"))] #![cfg_attr(target_env = "p2", unstable(feature = "wasip2", issue = "none"))] -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] #![doc(cfg(target_os = "wasi"))] pub mod ffi; diff --git a/std/src/os/wasip2/mod.rs b/std/src/os/wasip2/mod.rs index 1d44dd72814b..809a288f20d0 100644 --- a/std/src/os/wasip2/mod.rs +++ b/std/src/os/wasip2/mod.rs @@ -2,4 +2,5 @@ //! //! This module is currently empty, but will be filled over time as wasi-libc support for WASI Preview 2 is stabilized. +#![forbid(unsafe_op_in_unsafe_fn)] #![stable(feature = "raw_ext", since = "1.1.0")] diff --git a/std/src/sys/pal/wasi/args.rs b/std/src/sys/pal/wasi/args.rs index 6b6d1b8ff4e2..52cfa202af82 100644 --- a/std/src/sys/pal/wasi/args.rs +++ b/std/src/sys/pal/wasi/args.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use crate::ffi::{CStr, OsStr, OsString}; use crate::os::wasi::ffi::OsStrExt; diff --git a/std/src/sys/pal/wasi/env.rs b/std/src/sys/pal/wasi/env.rs index 730e356d7fe9..8d4449826736 100644 --- a/std/src/sys/pal/wasi/env.rs +++ b/std/src/sys/pal/wasi/env.rs @@ -1,3 +1,5 @@ +#![forbid(unsafe_op_in_unsafe_fn)] + pub mod os { pub const FAMILY: &str = ""; pub const OS: &str = ""; diff --git a/std/src/sys/pal/wasi/fd.rs b/std/src/sys/pal/wasi/fd.rs index 8966e4b80ad3..19b60157e2e0 100644 --- a/std/src/sys/pal/wasi/fd.rs +++ b/std/src/sys/pal/wasi/fd.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] #![allow(dead_code)] use super::err2io; diff --git a/std/src/sys/pal/wasi/fs.rs b/std/src/sys/pal/wasi/fs.rs index 11900886f0b5..6a97621ad50a 100644 --- a/std/src/sys/pal/wasi/fs.rs +++ b/std/src/sys/pal/wasi/fs.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use super::fd::WasiFd; use crate::ffi::{CStr, OsStr, OsString}; diff --git a/std/src/sys/pal/wasi/helpers.rs b/std/src/sys/pal/wasi/helpers.rs index 4b770ee23bc5..d047bf2fce85 100644 --- a/std/src/sys/pal/wasi/helpers.rs +++ b/std/src/sys/pal/wasi/helpers.rs @@ -1,3 +1,5 @@ +#![forbid(unsafe_op_in_unsafe_fn)] + use crate::{io as std_io, mem}; #[inline] diff --git a/std/src/sys/pal/wasi/io.rs b/std/src/sys/pal/wasi/io.rs index 2cd45df88fad..b7c2f03daa04 100644 --- a/std/src/sys/pal/wasi/io.rs +++ b/std/src/sys/pal/wasi/io.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use crate::marker::PhantomData; use crate::os::fd::{AsFd, AsRawFd}; diff --git a/std/src/sys/pal/wasi/net.rs b/std/src/sys/pal/wasi/net.rs index b4cf94c8781e..a64867998281 100644 --- a/std/src/sys/pal/wasi/net.rs +++ b/std/src/sys/pal/wasi/net.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use super::err2io; use super::fd::WasiFd; diff --git a/std/src/sys/pal/wasi/os.rs b/std/src/sys/pal/wasi/os.rs index f5b17d9df94b..f7701360f5a9 100644 --- a/std/src/sys/pal/wasi/os.rs +++ b/std/src/sys/pal/wasi/os.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use core::slice::memchr; diff --git a/std/src/sys/pal/wasi/stdio.rs b/std/src/sys/pal/wasi/stdio.rs index 4cc0e4ed5a45..ca49f871e195 100644 --- a/std/src/sys/pal/wasi/stdio.rs +++ b/std/src/sys/pal/wasi/stdio.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use super::fd::WasiFd; use crate::io::{self, IoSlice, IoSliceMut}; diff --git a/std/src/sys/pal/wasi/thread.rs b/std/src/sys/pal/wasi/thread.rs index c37acd8dfeeb..31c9cbd4699b 100644 --- a/std/src/sys/pal/wasi/thread.rs +++ b/std/src/sys/pal/wasi/thread.rs @@ -1,3 +1,5 @@ +#![forbid(unsafe_op_in_unsafe_fn)] + use crate::ffi::CStr; use crate::num::NonZero; use crate::sys::unsupported; @@ -73,13 +75,13 @@ impl Thread { if #[cfg(target_feature = "atomics")] { pub unsafe fn new(stack: usize, p: Box) -> io::Result { let p = Box::into_raw(Box::new(p)); - let mut native: libc::pthread_t = mem::zeroed(); - let mut attr: libc::pthread_attr_t = mem::zeroed(); - assert_eq!(libc::pthread_attr_init(&mut attr), 0); + let mut native: libc::pthread_t = unsafe { mem::zeroed() }; + let mut attr: libc::pthread_attr_t = unsafe { mem::zeroed() }; + assert_eq!(unsafe { libc::pthread_attr_init(&mut attr) }, 0); let stack_size = cmp::max(stack, DEFAULT_MIN_STACK_SIZE); - match libc::pthread_attr_setstacksize(&mut attr, stack_size) { + match unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) } { 0 => {} n => { assert_eq!(n, libc::EINVAL); @@ -90,20 +92,20 @@ impl Thread { let page_size = os::page_size(); let stack_size = (stack_size + page_size - 1) & (-(page_size as isize - 1) as usize - 1); - assert_eq!(libc::pthread_attr_setstacksize(&mut attr, stack_size), 0); + assert_eq!(unsafe { libc::pthread_attr_setstacksize(&mut attr, stack_size) }, 0); } }; - let ret = libc::pthread_create(&mut native, &attr, thread_start, p as *mut _); + let ret = unsafe { libc::pthread_create(&mut native, &attr, thread_start, p as *mut _) }; // Note: if the thread creation fails and this assert fails, then p will // be leaked. However, an alternative design could cause double-free // which is clearly worse. - assert_eq!(libc::pthread_attr_destroy(&mut attr), 0); + assert_eq!(unsafe {libc::pthread_attr_destroy(&mut attr) }, 0); return if ret != 0 { // The thread failed to start and as a result p was not consumed. Therefore, it is // safe to reconstruct the box so that it gets deallocated. - drop(Box::from_raw(p)); + unsafe { drop(Box::from_raw(p)); } Err(io::Error::from_raw_os_error(ret)) } else { Ok(Thread { id: native }) diff --git a/std/src/sys/pal/wasi/time.rs b/std/src/sys/pal/wasi/time.rs index 016b06efbdc6..0d8d0b59ac14 100644 --- a/std/src/sys/pal/wasi/time.rs +++ b/std/src/sys/pal/wasi/time.rs @@ -1,4 +1,4 @@ -#![deny(unsafe_op_in_unsafe_fn)] +#![forbid(unsafe_op_in_unsafe_fn)] use crate::time::Duration; From a9ad57eb6a180ca5e2b92e897f1ae190b8fd69fa Mon Sep 17 00:00:00 2001 From: "Chai T. Rex" Date: Wed, 21 Aug 2024 15:59:14 -0400 Subject: [PATCH 2/4] Use `assert_unsafe_precondition!` in `AsciiChar::digit_unchecked` --- core/src/ascii/ascii_char.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/core/src/ascii/ascii_char.rs b/core/src/ascii/ascii_char.rs index 375358dddf5c..ce09a0b444da 100644 --- a/core/src/ascii/ascii_char.rs +++ b/core/src/ascii/ascii_char.rs @@ -3,8 +3,8 @@ //! suggestions from rustc if you get anything slightly wrong in here, and overall //! helps with clarity as we're also referring to `char` intentionally in here. -use crate::fmt; use crate::mem::transmute; +use crate::{assert_unsafe_precondition, fmt}; /// One of the 128 Unicode characters from U+0000 through U+007F, /// often known as the [ASCII] subset. @@ -497,14 +497,18 @@ impl AsciiChar { /// Notably, it should not be expected to return hex digits, or any other /// reasonable extension of the decimal digits. /// - /// (This lose safety condition is intended to simplify soundness proofs + /// (This loose safety condition is intended to simplify soundness proofs /// when writing code using this method, since the implementation doesn't /// need something really specific, not to make those other arguments do /// something useful. It might be tightened before stabilization.) #[unstable(feature = "ascii_char", issue = "110998")] #[inline] pub const unsafe fn digit_unchecked(d: u8) -> Self { - debug_assert!(d < 10); + assert_unsafe_precondition!( + check_language_ub, + "`AsciiChar::digit_unchecked` input cannot exceed 9.", + (d: u8 = d) => d < 10 + ); // SAFETY: `'0'` through `'9'` are U+00030 through U+0039, // so because `d` must be 64 or less the addition can return at most From 9d2bb976994eecdacc458833fe8e8335597fd34d Mon Sep 17 00:00:00 2001 From: "Chai T. Rex" Date: Wed, 21 Aug 2024 16:39:13 -0400 Subject: [PATCH 3/4] Change `assert_unsafe_precondition` docs to refer to `check_language_ub` --- core/src/ub_checks.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/ub_checks.rs b/core/src/ub_checks.rs index b65b48c162d9..c1a8c34539e6 100644 --- a/core/src/ub_checks.rs +++ b/core/src/ub_checks.rs @@ -10,7 +10,7 @@ use crate::intrinsics::{self, const_eval_select}; /// macro for language UB are always ignored. /// /// This macro should be called as -/// `assert_unsafe_precondition!(check_{library,lang}_ub, "message", (ident: type = expr, ident: type = expr) => check_expr)` +/// `assert_unsafe_precondition!(check_{library,language}_ub, "message", (ident: type = expr, ident: type = expr) => check_expr)` /// where each `expr` will be evaluated and passed in as function argument `ident: type`. Then all /// those arguments are passed to a function with the body `check_expr`. /// Pick `check_language_ub` when this is guarding a violation of language UB, i.e., immediate UB From 863123bd7c4f12a56f81a6f752c20edf53ff04b4 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Wed, 21 Aug 2024 17:22:08 -0500 Subject: [PATCH 4/4] Add `const_cell_into_inner` to `OnceCell` `Cell` and `RefCell` have their `into_inner` methods const unstable. `OnceCell` has the same logic, so add it under the same gate. Tracking issue: https://github.com/rust-lang/rust/issues/78729 --- core/src/cell/once.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/cell/once.rs b/core/src/cell/once.rs index 097fa86c9381..87df8a4e272e 100644 --- a/core/src/cell/once.rs +++ b/core/src/cell/once.rs @@ -309,7 +309,8 @@ impl OnceCell { /// ``` #[inline] #[stable(feature = "once_cell", since = "1.70.0")] - pub fn into_inner(self) -> Option { + #[rustc_const_unstable(feature = "const_cell_into_inner", issue = "78729")] + pub const fn into_inner(self) -> Option { // Because `into_inner` takes `self` by value, the compiler statically verifies // that it is not currently borrowed. So it is safe to move out `Option`. self.inner.into_inner()