Merge branch 'mut-from-ref-tackle' into 'master'

make mut_from_ref deny

See merge request redox-os/relibc!1507
This commit is contained in:
Jeremy Soller
2026-07-02 08:27:52 -06:00
8 changed files with 25 additions and 5 deletions
+1 -1
View File
@@ -32,7 +32,7 @@ implicit_clone = "deny"
missing_errors_doc = "allow" # TODO review occurrences
missing_panics_doc = "allow" # TODO review occurrences
missing_safety_doc = "allow" # TODO review occurrences
mut_from_ref = "warn" # TODO review occurrences
mut_from_ref = "deny"
precedence = "deny"
ptr_as_ptr = "warn" # TODO review occurrences
ptr_cast_constness = "warn" # TODO review occurrences
+3
View File
@@ -15,6 +15,7 @@ pub struct iovec {
}
impl iovec {
#[expect(clippy::mut_from_ref)]
unsafe fn to_slice(&self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.iov_base.cast::<u8>(), self.iov_len) }
}
@@ -23,6 +24,7 @@ impl iovec {
pub unsafe fn gather(iovs: &[iovec]) -> Vec<u8> {
let mut vec = Vec::new();
for iov in iovs.iter() {
// SAFETY: only a single mutable reference created
vec.extend_from_slice(unsafe { iov.to_slice() });
}
vec
@@ -31,6 +33,7 @@ pub unsafe fn gather(iovs: &[iovec]) -> Vec<u8> {
pub unsafe fn scatter(iovs: &[iovec], vec: Vec<u8>) {
let mut i = 0;
for iov in iovs.iter() {
// SAFETY: only a single mutable reference created
let slice = unsafe { iov.to_slice() };
slice.copy_from_slice(&vec[i..][..slice.len()]);
i += slice.len();
+1 -1
View File
@@ -118,7 +118,7 @@ pub unsafe extern "C" fn posix_spawnp(
return errno::ENOENT;
}
let path_env = unsafe { CStr::from_ptr(path_env) };
for program_buf in PathSearchIter::new(&program.to_bytes(), &path_env) {
for program_buf in PathSearchIter::new(program.to_bytes(), &path_env) {
// SAFETY: CStr::from_ptr().to_bytes() always stop at null, no need to check again
let program_c = unsafe { CStr::from_bytes_with_nul_unchecked(program_buf.as_slice()) };
if Sys::access(program_c, F_OK).is_err() {
+1 -1
View File
@@ -384,7 +384,7 @@ pub unsafe extern "C" fn execvp(file: *const c_char, argv: *const *mut c_char) -
let path_env = unsafe { getenv(c"PATH".as_ptr()) };
if !path_env.is_null() {
let path_env = unsafe { CStr::from_ptr(path_env) };
for program_buf in PathSearchIter::new(&file.to_bytes(), &path_env) {
for program_buf in PathSearchIter::new(file.to_bytes(), &path_env) {
// SAFETY: CStr::from_ptr().to_bytes() always stop at null, no need to check again
let program_c =
unsafe { CStr::from_bytes_with_nul_unchecked(program_buf.as_slice()) };
+1
View File
@@ -135,6 +135,7 @@ impl MmapFile {
unsafe { core::slice::from_raw_parts(self.ptr.cast::<u8>(), self.size) }
}
#[expect(clippy::mut_from_ref)]
fn as_mut_slice(&self) -> &mut [u8] {
unsafe { core::slice::from_raw_parts_mut(self.ptr.cast::<u8>(), self.size) }
}
+1 -2
View File
@@ -321,8 +321,7 @@ pub unsafe fn get_auxvs(ptr: *const usize) -> Box<[[usize; 2]]> {
// TODO: Find an auxv replacement for Redox's execv protocol
#[cold]
pub unsafe fn get_auxv_raw(ptr: *const usize, requested_kind: usize) -> Option<usize> {
unsafe { auxv_iter(ptr) }
.find_map(|[kind, value]| Some(value).filter(|_| kind == requested_kind))
unsafe { auxv_iter(ptr) }.find_map(|[kind, value]| (kind == requested_kind).then_some(value))
}
pub fn get_auxv(auxvs: &[[usize; 2]], key: usize) -> Option<usize> {
auxvs
+5
View File
@@ -33,6 +33,11 @@ impl<T> RawCell<T> {
pub unsafe fn unsafe_set(&self, t: T) {
unsafe { *self.inner.get() = t };
}
/// # Safety
/// This allows creation of multiple mutable references from an immutable
/// reference. Caller must ensure this is not called on the same `RawCell`
/// multiple times.
#[expect(clippy::mut_from_ref, reason = "documented safety usage")]
#[inline]
pub unsafe fn unsafe_mut(&self) -> &mut T {
unsafe { &mut *self.inner.get() }
+12
View File
@@ -75,6 +75,12 @@ impl<T> Mutex<T> {
/// it's up to you to unlock it after mutex. Returns the last atomic value
/// on failure. You should probably not worry about this, it's used for
/// internal optimizations.
///
/// # Safety
/// This allows creation of multiple mutable references from an immutable
/// reference. Caller must ensure this is not called on the same `Mutex`
/// multiple times.
#[expect(clippy::mut_from_ref, reason = "documented safety usage")]
pub unsafe fn manual_try_lock(&self) -> Result<&mut T, c_int> {
if unsafe { manual_try_lock_generic(&self.lock) } {
Ok(unsafe { &mut *self.content.get() })
@@ -85,6 +91,12 @@ impl<T> Mutex<T> {
/// Lock the mutex, returning the inner content. After doing this, it's
/// your responsibility to unlock it after usage. Mostly useful for FFI:
/// Prefer normal .lock() where possible.
///
/// # Safety
/// This allows creation of multiple mutable references from an immutable
/// reference. Caller must ensure this is not called on the same `Mutex`
/// multiple times.
#[expect(clippy::mut_from_ref, reason = "documented safety usage")]
pub unsafe fn manual_lock(&self) -> &mut T {
unsafe { manual_lock_generic(&self.lock) };
unsafe { &mut *self.content.get() }