diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index fcd1c307b5af6..1f6a3e904795a 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1018,7 +1018,7 @@ where K: Borrow, Q: Hash + Eq, { - self.base.get_many_unchecked_mut(ks) + unsafe { self.base.get_many_unchecked_mut(ks) } } /// Returns `true` if the map contains a value for the specified key. diff --git a/library/std/src/env.rs b/library/std/src/env.rs index 2f35e721610e0..36add02d68c5c 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -366,11 +366,8 @@ impl Error for VarError { #[rustc_deprecated_safe_2024] #[stable(feature = "env", since = "1.0.0")] pub unsafe fn set_var, V: AsRef>(key: K, value: V) { - _set_var(key.as_ref(), value.as_ref()) -} - -unsafe fn _set_var(key: &OsStr, value: &OsStr) { - os_imp::setenv(key, value).unwrap_or_else(|e| { + let (key, value) = (key.as_ref(), value.as_ref()); + unsafe { os_imp::setenv(key, value) }.unwrap_or_else(|e| { panic!("failed to set environment variable `{key:?}` to `{value:?}`: {e}") }) } @@ -433,11 +430,8 @@ unsafe fn _set_var(key: &OsStr, value: &OsStr) { #[rustc_deprecated_safe_2024] #[stable(feature = "env", since = "1.0.0")] pub unsafe fn remove_var>(key: K) { - _remove_var(key.as_ref()) -} - -unsafe fn _remove_var(key: &OsStr) { - os_imp::unsetenv(key) + let key = key.as_ref(); + unsafe { os_imp::unsetenv(key) } .unwrap_or_else(|e| panic!("failed to remove environment variable `{key:?}`: {e}")) } diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 4a417c84a30a5..f9dba08da4c3c 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -184,7 +184,7 @@ impl OsString { #[inline] #[stable(feature = "os_str_bytes", since = "1.74.0")] pub unsafe fn from_encoded_bytes_unchecked(bytes: Vec) -> Self { - OsString { inner: Buf::from_encoded_bytes_unchecked(bytes) } + OsString { inner: unsafe { Buf::from_encoded_bytes_unchecked(bytes) } } } /// Converts to an [`OsStr`] slice. @@ -813,7 +813,7 @@ impl OsStr { #[inline] #[stable(feature = "os_str_bytes", since = "1.74.0")] pub unsafe fn from_encoded_bytes_unchecked(bytes: &[u8]) -> &Self { - Self::from_inner(Slice::from_encoded_bytes_unchecked(bytes)) + Self::from_inner(unsafe { Slice::from_encoded_bytes_unchecked(bytes) }) } #[inline] diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs index 1768bb05ddbcb..a8680e9b6ead1 100644 --- a/library/std/src/io/buffered/bufwriter.rs +++ b/library/std/src/io/buffered/bufwriter.rs @@ -433,9 +433,11 @@ impl BufWriter { let old_len = self.buf.len(); let buf_len = buf.len(); let src = buf.as_ptr(); - let dst = self.buf.as_mut_ptr().add(old_len); - ptr::copy_nonoverlapping(src, dst, buf_len); - self.buf.set_len(old_len + buf_len); + unsafe { + let dst = self.buf.as_mut_ptr().add(old_len); + ptr::copy_nonoverlapping(src, dst, buf_len); + self.buf.set_len(old_len + buf_len); + } } #[inline] diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index a1a8b2a3505c7..2ed64a40495ef 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -482,7 +482,7 @@ where A: Allocator, { debug_assert!(vec.capacity() >= pos + buf.len()); - vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()); + unsafe { vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()) }; pos + buf.len() } diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs index a5cefe2292be4..fbb74967df3f1 100644 --- a/library/std/src/io/error/repr_bitpacked.rs +++ b/library/std/src/io/error/repr_bitpacked.rs @@ -267,11 +267,14 @@ where // Using this rather than unwrap meaningfully improves the code // for callers which only care about one variant (usually // `Custom`) - core::hint::unreachable_unchecked(); + unsafe { core::hint::unreachable_unchecked() }; }); ErrorData::Simple(kind) } - TAG_SIMPLE_MESSAGE => ErrorData::SimpleMessage(&*ptr.cast::().as_ptr()), + TAG_SIMPLE_MESSAGE => { + // SAFETY: per tag + unsafe { ErrorData::SimpleMessage(&*ptr.cast::().as_ptr()) } + } TAG_CUSTOM => { // It would be correct for us to use `ptr::byte_sub` here (see the // comment above the `wrapping_add` call in `new_custom` for why), diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index b464461277a0f..1345a30361e28 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -382,11 +382,11 @@ pub(crate) unsafe fn append_to_string(buf: &mut String, f: F) -> Result) -> Result, { - let mut g = Guard { len: buf.len(), buf: buf.as_mut_vec() }; + let mut g = Guard { len: buf.len(), buf: unsafe { buf.as_mut_vec() } }; let ret = f(g.buf); // SAFETY: the caller promises to only append data to `buf` - let appended = g.buf.get_unchecked(g.len..); + let appended = unsafe { g.buf.get_unchecked(g.len..) }; if str::from_utf8(appended).is_err() { ret.and_then(|_| Err(Error::INVALID_UTF8)) } else { diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 66aeb35aceec0..d4d68c2068d8a 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -252,6 +252,7 @@ #![allow(internal_features)] #![deny(rustc::existing_doc_keyword)] #![deny(fuzzy_provenance_casts)] +#![deny(unsafe_op_in_unsafe_fn)] #![allow(rustdoc::redundant_explicit_links)] // Ensure that std can be linked against panic_abort despite compiled with `-C panic=unwind` #![deny(ffi_unwind_calls)] @@ -664,7 +665,7 @@ pub mod alloc; mod panicking; #[path = "../../backtrace/src/lib.rs"] -#[allow(dead_code, unused_attributes, fuzzy_provenance_casts)] +#[allow(dead_code, unused_attributes, fuzzy_provenance_casts, unsafe_op_in_unsafe_fn)] mod backtrace_rs; // Re-export macros defined in core. diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs index 455fdd3c34d77..020a8b324f410 100644 --- a/library/std/src/os/mod.rs +++ b/library/std/src/os/mod.rs @@ -2,6 +2,7 @@ #![stable(feature = "os", since = "1.0.0")] #![allow(missing_docs, nonstandard_style, missing_debug_implementations)] +#![allow(unsafe_op_in_unsafe_fn)] pub mod raw; diff --git a/library/std/src/os/windows/io/raw.rs b/library/std/src/os/windows/io/raw.rs index 770583a9ce3e0..343cc6e4a8a5a 100644 --- a/library/std/src/os/windows/io/raw.rs +++ b/library/std/src/os/windows/io/raw.rs @@ -159,10 +159,12 @@ fn stdio_handle(raw: RawHandle) -> RawHandle { impl FromRawHandle for fs::File { #[inline] unsafe fn from_raw_handle(handle: RawHandle) -> fs::File { - let handle = handle as sys::c::HANDLE; - fs::File::from_inner(sys::fs::File::from_inner(FromInner::from_inner( - OwnedHandle::from_raw_handle(handle), - ))) + unsafe { + let handle = handle as sys::c::HANDLE; + fs::File::from_inner(sys::fs::File::from_inner(FromInner::from_inner( + OwnedHandle::from_raw_handle(handle), + ))) + } } } @@ -260,24 +262,30 @@ impl AsRawSocket for net::UdpSocket { impl FromRawSocket for net::TcpStream { #[inline] unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpStream { - let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock)); - net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(sock)) + unsafe { + let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock)); + net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(sock)) + } } } #[stable(feature = "from_raw_os", since = "1.1.0")] impl FromRawSocket for net::TcpListener { #[inline] unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpListener { - let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock)); - net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(sock)) + unsafe { + let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock)); + net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(sock)) + } } } #[stable(feature = "from_raw_os", since = "1.1.0")] impl FromRawSocket for net::UdpSocket { #[inline] unsafe fn from_raw_socket(sock: RawSocket) -> net::UdpSocket { - let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock)); - net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(sock)) + unsafe { + let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock)); + net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(sock)) + } } } diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs index 6ffdf907c8ed3..4334d041439d9 100644 --- a/library/std/src/os/windows/io/socket.rs +++ b/library/std/src/os/windows/io/socket.rs @@ -76,7 +76,7 @@ impl BorrowedSocket<'_> { #[stable(feature = "io_safety", since = "1.63.0")] pub const unsafe fn borrow_raw(socket: RawSocket) -> Self { assert!(socket != sys::c::INVALID_SOCKET as RawSocket); - Self { socket, _phantom: PhantomData } + unsafe { Self { socket, _phantom: PhantomData } } } } @@ -201,8 +201,10 @@ impl IntoRawSocket for OwnedSocket { impl FromRawSocket for OwnedSocket { #[inline] unsafe fn from_raw_socket(socket: RawSocket) -> Self { - debug_assert_ne!(socket, sys::c::INVALID_SOCKET as RawSocket); - Self { socket } + unsafe { + debug_assert_ne!(socket, sys::c::INVALID_SOCKET as RawSocket); + Self { socket } + } } } diff --git a/library/std/src/os/windows/mod.rs b/library/std/src/os/windows/mod.rs index 52eb3b7c06769..f452403ee8426 100644 --- a/library/std/src/os/windows/mod.rs +++ b/library/std/src/os/windows/mod.rs @@ -24,6 +24,7 @@ #![stable(feature = "rust1", since = "1.0.0")] #![doc(cfg(windows))] +#![deny(unsafe_op_in_unsafe_fn)] pub mod ffi; pub mod fs; diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 05ffb8925a1f0..3927b2ed9bb5c 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -16,7 +16,7 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; #[stable(feature = "process_extensions", since = "1.2.0")] impl FromRawHandle for process::Stdio { unsafe fn from_raw_handle(handle: RawHandle) -> process::Stdio { - let handle = sys::handle::Handle::from_raw_handle(handle as *mut _); + let handle = unsafe { sys::handle::Handle::from_raw_handle(handle as *mut _) }; let io = sys::process::Stdio::Handle(handle); process::Stdio::from_inner(io) } @@ -407,7 +407,7 @@ impl CommandExt for process::Command { attribute: usize, value: T, ) -> &mut process::Command { - self.as_inner_mut().raw_attribute(attribute, value); + unsafe { self.as_inner_mut().raw_attribute(attribute, value) }; self } } diff --git a/library/std/src/process/tests.rs b/library/std/src/process/tests.rs index b4f6bb71c79c4..055601d030799 100644 --- a/library/std/src/process/tests.rs +++ b/library/std/src/process/tests.rs @@ -385,29 +385,25 @@ fn test_interior_nul_in_env_value_is_error() { #[cfg(windows)] fn test_creation_flags() { use crate::os::windows::process::CommandExt; - use crate::sys::c::{BOOL, DWORD, INFINITE}; + use crate::sys::c::{BOOL, INFINITE}; #[repr(C)] struct DEBUG_EVENT { - pub event_code: DWORD, - pub process_id: DWORD, - pub thread_id: DWORD, + pub event_code: u32, + pub process_id: u32, + pub thread_id: u32, // This is a union in the real struct, but we don't // need this data for the purposes of this test. pub _junk: [u8; 164], } extern "system" { - fn WaitForDebugEvent(lpDebugEvent: *mut DEBUG_EVENT, dwMilliseconds: DWORD) -> BOOL; - fn ContinueDebugEvent( - dwProcessId: DWORD, - dwThreadId: DWORD, - dwContinueStatus: DWORD, - ) -> BOOL; + fn WaitForDebugEvent(lpDebugEvent: *mut DEBUG_EVENT, dwMilliseconds: u32) -> BOOL; + fn ContinueDebugEvent(dwProcessId: u32, dwThreadId: u32, dwContinueStatus: u32) -> BOOL; } - const DEBUG_PROCESS: DWORD = 1; - const EXIT_PROCESS_DEBUG_EVENT: DWORD = 5; - const DBG_EXCEPTION_NOT_HANDLED: DWORD = 0x80010001; + const DEBUG_PROCESS: u32 = 1; + const EXIT_PROCESS_DEBUG_EVENT: u32 = 5; + const DBG_EXCEPTION_NOT_HANDLED: u32 = 0x80010001; let mut child = Command::new("cmd").creation_flags(DEBUG_PROCESS).stdin(Stdio::piped()).spawn().unwrap(); diff --git a/library/std/src/sync/mpmc/array.rs b/library/std/src/sync/mpmc/array.rs index 492e21d9bdb63..185319add745f 100644 --- a/library/std/src/sync/mpmc/array.rs +++ b/library/std/src/sync/mpmc/array.rs @@ -200,11 +200,12 @@ impl Channel { return Err(msg); } - let slot: &Slot = &*(token.array.slot as *const Slot); - // Write the message into the slot and update the stamp. - slot.msg.get().write(MaybeUninit::new(msg)); - slot.stamp.store(token.array.stamp, Ordering::Release); + unsafe { + let slot: &Slot = &*(token.array.slot as *const Slot); + slot.msg.get().write(MaybeUninit::new(msg)); + slot.stamp.store(token.array.stamp, Ordering::Release); + } // Wake a sleeping receiver. self.receivers.notify(); @@ -291,11 +292,14 @@ impl Channel { return Err(()); } - let slot: &Slot = &*(token.array.slot as *const Slot); - // Read the message from the slot and update the stamp. - let msg = slot.msg.get().read().assume_init(); - slot.stamp.store(token.array.stamp, Ordering::Release); + let msg = unsafe { + let slot: &Slot = &*(token.array.slot as *const Slot); + + let msg = slot.msg.get().read().assume_init(); + slot.stamp.store(token.array.stamp, Ordering::Release); + msg + }; // Wake a sleeping sender. self.senders.notify(); @@ -471,7 +475,7 @@ impl Channel { false }; - self.discard_all_messages(tail); + unsafe { self.discard_all_messages(tail) }; disconnected } diff --git a/library/std/src/sync/mpmc/counter.rs b/library/std/src/sync/mpmc/counter.rs index a5a6bdc67f13f..3478cf41dc9d2 100644 --- a/library/std/src/sync/mpmc/counter.rs +++ b/library/std/src/sync/mpmc/counter.rs @@ -63,7 +63,7 @@ impl Sender { disconnect(&self.counter().chan); if self.counter().destroy.swap(true, Ordering::AcqRel) { - drop(Box::from_raw(self.counter)); + drop(unsafe { Box::from_raw(self.counter) }); } } } @@ -116,7 +116,7 @@ impl Receiver { disconnect(&self.counter().chan); if self.counter().destroy.swap(true, Ordering::AcqRel) { - drop(Box::from_raw(self.counter)); + drop(unsafe { Box::from_raw(self.counter) }); } } } diff --git a/library/std/src/sync/mpmc/list.rs b/library/std/src/sync/mpmc/list.rs index 9e7148c716cda..edac7a0cb1835 100644 --- a/library/std/src/sync/mpmc/list.rs +++ b/library/std/src/sync/mpmc/list.rs @@ -91,7 +91,7 @@ impl Block { // It is not necessary to set the `DESTROY` bit in the last slot because that slot has // begun destruction of the block. for i in start..BLOCK_CAP - 1 { - let slot = (*this).slots.get_unchecked(i); + let slot = unsafe { (*this).slots.get_unchecked(i) }; // Mark the `DESTROY` bit if a thread is still using the slot. if slot.state.load(Ordering::Acquire) & READ == 0 @@ -103,7 +103,7 @@ impl Block { } // No thread is using the block, now it is safe to destroy it. - drop(Box::from_raw(this)); + drop(unsafe { Box::from_raw(this) }); } } @@ -265,9 +265,11 @@ impl Channel { // Write the message into the slot. let block = token.list.block as *mut Block; let offset = token.list.offset; - let slot = (*block).slots.get_unchecked(offset); - slot.msg.get().write(MaybeUninit::new(msg)); - slot.state.fetch_or(WRITE, Ordering::Release); + unsafe { + let slot = (*block).slots.get_unchecked(offset); + slot.msg.get().write(MaybeUninit::new(msg)); + slot.state.fetch_or(WRITE, Ordering::Release); + } // Wake a sleeping receiver. self.receivers.notify(); @@ -369,19 +371,21 @@ impl Channel { // Read the message. let block = token.list.block as *mut Block; let offset = token.list.offset; - let slot = (*block).slots.get_unchecked(offset); - slot.wait_write(); - let msg = slot.msg.get().read().assume_init(); - - // Destroy the block if we've reached the end, or if another thread wanted to destroy but - // couldn't because we were busy reading from the slot. - if offset + 1 == BLOCK_CAP { - Block::destroy(block, 0); - } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { - Block::destroy(block, offset + 1); - } + unsafe { + let slot = (*block).slots.get_unchecked(offset); + slot.wait_write(); + let msg = slot.msg.get().read().assume_init(); + + // Destroy the block if we've reached the end, or if another thread wanted to destroy but + // couldn't because we were busy reading from the slot. + if offset + 1 == BLOCK_CAP { + Block::destroy(block, 0); + } else if slot.state.fetch_or(READ, Ordering::AcqRel) & DESTROY != 0 { + Block::destroy(block, offset + 1); + } - Ok(msg) + Ok(msg) + } } /// Attempts to send a message into the channel. diff --git a/library/std/src/sync/mpmc/zero.rs b/library/std/src/sync/mpmc/zero.rs index 1b82713edc748..6d1c9d64e7a7a 100644 --- a/library/std/src/sync/mpmc/zero.rs +++ b/library/std/src/sync/mpmc/zero.rs @@ -103,9 +103,11 @@ impl Channel { return Err(msg); } - let packet = &*(token.zero.0 as *const Packet); - packet.msg.get().write(Some(msg)); - packet.ready.store(true, Ordering::Release); + unsafe { + let packet = &*(token.zero.0 as *const Packet); + packet.msg.get().write(Some(msg)); + packet.ready.store(true, Ordering::Release); + } Ok(()) } @@ -116,22 +118,24 @@ impl Channel { return Err(()); } - let packet = &*(token.zero.0 as *const Packet); + let packet = unsafe { &*(token.zero.0 as *const Packet) }; if packet.on_stack { // The message has been in the packet from the beginning, so there is no need to wait // for it. However, after reading the message, we need to set `ready` to `true` in // order to signal that the packet can be destroyed. - let msg = packet.msg.get().replace(None).unwrap(); + let msg = unsafe { packet.msg.get().replace(None) }.unwrap(); packet.ready.store(true, Ordering::Release); Ok(msg) } else { // Wait until the message becomes available, then read it and destroy the // heap-allocated packet. packet.wait_ready(); - let msg = packet.msg.get().replace(None).unwrap(); - drop(Box::from_raw(token.zero.0 as *mut Packet)); - Ok(msg) + unsafe { + let msg = packet.msg.get().replace(None).unwrap(); + drop(Box::from_raw(token.zero.0 as *mut Packet)); + Ok(msg) + } } } diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index fe243550606f3..94955beaf37b7 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -502,7 +502,7 @@ impl OnceLock { #[inline] unsafe fn get_unchecked(&self) -> &T { debug_assert!(self.is_initialized()); - (&*self.value.get()).assume_init_ref() + unsafe { (&*self.value.get()).assume_init_ref() } } /// # Safety @@ -511,7 +511,7 @@ impl OnceLock { #[inline] unsafe fn get_unchecked_mut(&mut self) -> &mut T { debug_assert!(self.is_initialized()); - (&mut *self.value.get()).assume_init_mut() + unsafe { (&mut *self.value.get()).assume_init_mut() } } } diff --git a/library/std/src/sync/reentrant_lock.rs b/library/std/src/sync/reentrant_lock.rs index f7fe8eb1c7fd5..042c439394e06 100644 --- a/library/std/src/sync/reentrant_lock.rs +++ b/library/std/src/sync/reentrant_lock.rs @@ -244,7 +244,9 @@ impl ReentrantLock { } unsafe fn increment_lock_count(&self) -> Option<()> { - *self.lock_count.get() = (*self.lock_count.get()).checked_add(1)?; + unsafe { + *self.lock_count.get() = (*self.lock_count.get()).checked_add(1)?; + } Some(()) } } diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs index e0a8a7603d71a..a4ec52a4abe63 100644 --- a/library/std/src/sync/rwlock.rs +++ b/library/std/src/sync/rwlock.rs @@ -578,7 +578,7 @@ impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> { // successfully called from the same thread before instantiating this object. unsafe fn new(lock: &'rwlock RwLock) -> LockResult> { poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard { - data: NonNull::new_unchecked(lock.data.get()), + data: unsafe { NonNull::new_unchecked(lock.data.get()) }, inner_lock: &lock.inner, }) } diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs index 4092e6080d548..e50758ce00d8b 100644 --- a/library/std/src/sys/mod.rs +++ b/library/std/src/sys/mod.rs @@ -1,3 +1,5 @@ +#![allow(unsafe_op_in_unsafe_fn)] + /// The PAL (platform abstraction layer) contains platform-specific abstractions /// for implementing the features in the other submodules, e.g. UNIX file /// descriptors. diff --git a/library/std/src/sys/pal/windows/alloc.rs b/library/std/src/sys/pal/windows/alloc.rs index e6cbdb6ef7d64..9f0194492b0a3 100644 --- a/library/std/src/sys/pal/windows/alloc.rs +++ b/library/std/src/sys/pal/windows/alloc.rs @@ -15,7 +15,7 @@ mod tests; // See https://docs.microsoft.com/windows/win32/api/heapapi/ // Flag to indicate that the memory returned by `HeapAlloc` should be zeroed. -const HEAP_ZERO_MEMORY: c::DWORD = 0x00000008; +const HEAP_ZERO_MEMORY: u32 = 0x00000008; // Get a handle to the default heap of the current process, or null if the operation fails. // @@ -113,9 +113,9 @@ fn init_or_get_process_heap() -> c::HANDLE { #[cold] extern "C" fn process_heap_init_and_alloc( _heap: MaybeUninit, // We pass this argument to match the ABI of `HeapAlloc` - flags: c::DWORD, - dwBytes: c::SIZE_T, -) -> c::LPVOID { + flags: u32, + dwBytes: usize, +) -> *mut c_void { let heap = init_or_get_process_heap(); if core::intrinsics::unlikely(heap.is_null()) { return ptr::null_mut(); @@ -127,9 +127,9 @@ extern "C" fn process_heap_init_and_alloc( #[inline(never)] fn process_heap_alloc( _heap: MaybeUninit, // We pass this argument to match the ABI of `HeapAlloc`, - flags: c::DWORD, - dwBytes: c::SIZE_T, -) -> c::LPVOID { + flags: u32, + dwBytes: usize, +) -> *mut c_void { let heap = HEAP.load(Ordering::Relaxed); if core::intrinsics::likely(!heap.is_null()) { // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`. @@ -240,7 +240,7 @@ unsafe impl GlobalAlloc for System { // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`, // `block` is a pointer to the start of an allocated block. - unsafe { HeapFree(heap, 0, block as c::LPVOID) }; + unsafe { HeapFree(heap, 0, block.cast::()) }; } #[inline] @@ -253,7 +253,7 @@ unsafe impl GlobalAlloc for System { // SAFETY: `heap` is a non-null handle returned by `GetProcessHeap`, // `ptr` is a pointer to the start of an allocated block. // The returned pointer points to the start of an allocated block. - unsafe { HeapReAlloc(heap, 0, ptr as c::LPVOID, new_size) as *mut u8 } + unsafe { HeapReAlloc(heap, 0, ptr.cast::(), new_size).cast::() } } else { // SAFETY: `realloc_fallback` is implemented using `dealloc` and `alloc`, which will // correctly handle `ptr` and return a pointer satisfying the guarantees of `System` diff --git a/library/std/src/sys/pal/windows/api.rs b/library/std/src/sys/pal/windows/api.rs index 17a0e47ad5950..00c816a6c09b8 100644 --- a/library/std/src/sys/pal/windows/api.rs +++ b/library/std/src/sys/pal/windows/api.rs @@ -227,8 +227,10 @@ pub fn set_file_information_by_handle( info: *const c_void, size: u32, ) -> Result<(), WinError> { - let result = c::SetFileInformationByHandle(handle, class, info, size); - (result != 0).then_some(()).ok_or_else(get_last_error) + unsafe { + let result = c::SetFileInformationByHandle(handle, class, info, size); + (result != 0).then_some(()).ok_or_else(get_last_error) + } } // SAFETY: The `SetFileInformation` trait ensures that this is safe. unsafe { set_info(handle, T::CLASS, info.as_ptr(), info.size()) } diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs index 7dfda4f714c77..296d19a926d96 100644 --- a/library/std/src/sys/pal/windows/c.rs +++ b/library/std/src/sys/pal/windows/c.rs @@ -4,12 +4,11 @@ #![cfg_attr(test, allow(dead_code))] #![unstable(issue = "none", feature = "windows_c")] #![allow(clippy::style)] +#![allow(unsafe_op_in_unsafe_fn)] use crate::ffi::CStr; use crate::mem; -use crate::num::NonZero; -pub use crate::os::raw::c_int; -use crate::os::raw::{c_char, c_long, c_longlong, c_uint, c_ulong, c_ushort, c_void}; +use crate::os::raw::{c_char, c_int, c_uint, c_ulong, c_ushort, c_void}; use crate::os::windows::io::{AsRawHandle, BorrowedHandle}; use crate::ptr; @@ -18,30 +17,10 @@ pub(super) mod windows_targets; mod windows_sys; pub use windows_sys::*; -pub type DWORD = c_ulong; -pub type NonZeroDWORD = NonZero; -pub type LARGE_INTEGER = c_longlong; -#[cfg_attr(target_vendor = "uwp", allow(unused))] -pub type LONG = c_long; -pub type UINT = c_uint; pub type WCHAR = u16; -pub type USHORT = c_ushort; -pub type SIZE_T = usize; -pub type CHAR = c_char; -pub type ULONG = c_ulong; - -pub type LPCVOID = *const c_void; -pub type LPOVERLAPPED = *mut OVERLAPPED; -pub type LPSECURITY_ATTRIBUTES = *mut SECURITY_ATTRIBUTES; -pub type LPVOID = *mut c_void; -pub type LPWCH = *mut WCHAR; -pub type LPWSTR = *mut WCHAR; - -#[cfg(target_vendor = "win7")] -pub type PSRWLOCK = *mut SRWLOCK; pub type socklen_t = c_int; -pub type ADDRESS_FAMILY = USHORT; +pub type ADDRESS_FAMILY = c_ushort; pub use FD_SET as fd_set; pub use LINGER as linger; pub use TIMEVAL as timeval; @@ -151,25 +130,25 @@ pub struct MOUNT_POINT_REPARSE_BUFFER { #[repr(C)] pub struct SOCKADDR_STORAGE_LH { pub ss_family: ADDRESS_FAMILY, - pub __ss_pad1: [CHAR; 6], + pub __ss_pad1: [c_char; 6], pub __ss_align: i64, - pub __ss_pad2: [CHAR; 112], + pub __ss_pad2: [c_char; 112], } #[repr(C)] #[derive(Copy, Clone)] pub struct sockaddr_in { pub sin_family: ADDRESS_FAMILY, - pub sin_port: USHORT, + pub sin_port: c_ushort, pub sin_addr: in_addr, - pub sin_zero: [CHAR; 8], + pub sin_zero: [c_char; 8], } #[repr(C)] #[derive(Copy, Clone)] pub struct sockaddr_in6 { pub sin6_family: ADDRESS_FAMILY, - pub sin6_port: USHORT, + pub sin6_port: c_ushort, pub sin6_flowinfo: c_ulong, pub sin6_addr: in6_addr, pub sin6_scope_id: c_ulong, @@ -271,9 +250,9 @@ pub unsafe fn NtReadFile( apccontext: *mut c_void, iostatusblock: &mut IO_STATUS_BLOCK, buffer: *mut crate::mem::MaybeUninit, - length: ULONG, - byteoffset: Option<&LARGE_INTEGER>, - key: Option<&ULONG>, + length: u32, + byteoffset: Option<&i64>, + key: Option<&u32>, ) -> NTSTATUS { windows_sys::NtReadFile( filehandle.as_raw_handle(), @@ -294,9 +273,9 @@ pub unsafe fn NtWriteFile( apccontext: *mut c_void, iostatusblock: &mut IO_STATUS_BLOCK, buffer: *const u8, - length: ULONG, - byteoffset: Option<&LARGE_INTEGER>, - key: Option<&ULONG>, + length: u32, + byteoffset: Option<&i64>, + key: Option<&u32>, ) -> NTSTATUS { windows_sys::NtWriteFile( filehandle.as_raw_handle(), @@ -336,13 +315,13 @@ compat_fn_with_fallback! { // >= Win10 1607 // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription pub fn SetThreadDescription(hthread: HANDLE, lpthreaddescription: PCWSTR) -> HRESULT { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL } // >= Win10 1607 // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreaddescription pub fn GetThreadDescription(hthread: HANDLE, lpthreaddescription: *mut PWSTR) -> HRESULT { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL + SetLastError(ERROR_CALL_NOT_IMPLEMENTED as u32); E_NOTIMPL } // >= Win8 / Server 2012 @@ -403,27 +382,27 @@ compat_fn_with_fallback! { #[cfg(target_vendor = "win7")] pub fn NtCreateKeyedEvent( KeyedEventHandle: *mut HANDLE, - DesiredAccess: DWORD, - ObjectAttributes: LPVOID, - Flags: ULONG + DesiredAccess: u32, + ObjectAttributes: *mut c_void, + Flags: u32 ) -> NTSTATUS { panic!("keyed events not available") } #[cfg(target_vendor = "win7")] pub fn NtReleaseKeyedEvent( EventHandle: HANDLE, - Key: LPVOID, + Key: *const c_void, Alertable: BOOLEAN, - Timeout: *mut c_longlong + Timeout: *mut i64 ) -> NTSTATUS { panic!("keyed events not available") } #[cfg(target_vendor = "win7")] pub fn NtWaitForKeyedEvent( EventHandle: HANDLE, - Key: LPVOID, + Key: *const c_void, Alertable: BOOLEAN, - Timeout: *mut c_longlong + Timeout: *mut i64 ) -> NTSTATUS { panic!("keyed events not available") } @@ -453,9 +432,9 @@ compat_fn_with_fallback! { apccontext: *mut c_void, iostatusblock: &mut IO_STATUS_BLOCK, buffer: *mut crate::mem::MaybeUninit, - length: ULONG, - byteoffset: Option<&LARGE_INTEGER>, - key: Option<&ULONG> + length: u32, + byteoffset: Option<&i64>, + key: Option<&u32> ) -> NTSTATUS { STATUS_NOT_IMPLEMENTED } @@ -467,9 +446,9 @@ compat_fn_with_fallback! { apccontext: *mut c_void, iostatusblock: &mut IO_STATUS_BLOCK, buffer: *const u8, - length: ULONG, - byteoffset: Option<&LARGE_INTEGER>, - key: Option<&ULONG> + length: u32, + byteoffset: Option<&i64>, + key: Option<&u32> ) -> NTSTATUS { STATUS_NOT_IMPLEMENTED } diff --git a/library/std/src/sys/pal/windows/compat.rs b/library/std/src/sys/pal/windows/compat.rs index f5d57a28db69a..49fa1603f3e1e 100644 --- a/library/std/src/sys/pal/windows/compat.rs +++ b/library/std/src/sys/pal/windows/compat.rs @@ -112,8 +112,10 @@ impl Module { /// (e.g. kernel32 and ntdll). pub unsafe fn new(name: &CStr) -> Option { // SAFETY: A CStr is always null terminated. - let module = c::GetModuleHandleA(name.as_ptr().cast::()); - NonNull::new(module).map(Self) + unsafe { + let module = c::GetModuleHandleA(name.as_ptr().cast::()); + NonNull::new(module).map(Self) + } } // Try to get the address of a function. diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs index cc68f5ef5f08c..85fd9153d5370 100644 --- a/library/std/src/sys/pal/windows/fs.rs +++ b/library/std/src/sys/pal/windows/fs.rs @@ -1,3 +1,4 @@ +#![allow(unsafe_op_in_unsafe_fn)] use core::ptr::addr_of; use crate::os::windows::prelude::*; @@ -28,12 +29,12 @@ pub struct File { #[derive(Clone)] pub struct FileAttr { - attributes: c::DWORD, + attributes: u32, creation_time: c::FILETIME, last_access_time: c::FILETIME, last_write_time: c::FILETIME, file_size: u64, - reparse_tag: c::DWORD, + reparse_tag: u32, volume_serial_number: Option, number_of_links: Option, file_index: Option, @@ -41,8 +42,8 @@ pub struct FileAttr { #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct FileType { - attributes: c::DWORD, - reparse_tag: c::DWORD, + attributes: u32, + reparse_tag: u32, } pub struct ReadDir { @@ -75,16 +76,16 @@ pub struct OpenOptions { create_new: bool, // system-specific custom_flags: u32, - access_mode: Option, - attributes: c::DWORD, - share_mode: c::DWORD, - security_qos_flags: c::DWORD, - security_attributes: c::LPSECURITY_ATTRIBUTES, + access_mode: Option, + attributes: u32, + share_mode: u32, + security_qos_flags: u32, + security_attributes: *mut c::SECURITY_ATTRIBUTES, } #[derive(Clone, PartialEq, Eq, Debug)] pub struct FilePermissions { - attrs: c::DWORD, + attrs: u32, } #[derive(Copy, Clone, Debug, Default)] @@ -241,11 +242,11 @@ impl OpenOptions { // receive is `SECURITY_ANONYMOUS = 0x0`, which we can't check for later on. self.security_qos_flags = flags | c::SECURITY_SQOS_PRESENT; } - pub fn security_attributes(&mut self, attrs: c::LPSECURITY_ATTRIBUTES) { + pub fn security_attributes(&mut self, attrs: *mut c::SECURITY_ATTRIBUTES) { self.security_attributes = attrs; } - fn get_access_mode(&self) -> io::Result { + fn get_access_mode(&self) -> io::Result { match (self.read, self.write, self.append, self.access_mode) { (.., Some(mode)) => Ok(mode), (true, false, false, None) => Ok(c::GENERIC_READ), @@ -261,7 +262,7 @@ impl OpenOptions { } } - fn get_creation_mode(&self) -> io::Result { + fn get_creation_mode(&self) -> io::Result { match (self.write, self.append) { (true, false) => {} (false, false) => { @@ -287,7 +288,7 @@ impl OpenOptions { }) } - fn get_flags_and_attributes(&self) -> c::DWORD { + fn get_flags_and_attributes(&self) -> u32 { self.custom_flags | self.attributes | self.security_qos_flags @@ -397,21 +398,21 @@ impl File { self.handle.as_raw_handle(), c::FileBasicInfo, core::ptr::addr_of_mut!(info) as *mut c_void, - size as c::DWORD, + size as u32, ))?; let mut attr = FileAttr { attributes: info.FileAttributes, creation_time: c::FILETIME { - dwLowDateTime: info.CreationTime as c::DWORD, - dwHighDateTime: (info.CreationTime >> 32) as c::DWORD, + dwLowDateTime: info.CreationTime as u32, + dwHighDateTime: (info.CreationTime >> 32) as u32, }, last_access_time: c::FILETIME { - dwLowDateTime: info.LastAccessTime as c::DWORD, - dwHighDateTime: (info.LastAccessTime >> 32) as c::DWORD, + dwLowDateTime: info.LastAccessTime as u32, + dwHighDateTime: (info.LastAccessTime >> 32) as u32, }, last_write_time: c::FILETIME { - dwLowDateTime: info.LastWriteTime as c::DWORD, - dwHighDateTime: (info.LastWriteTime >> 32) as c::DWORD, + dwLowDateTime: info.LastWriteTime as u32, + dwHighDateTime: (info.LastWriteTime >> 32) as u32, }, file_size: 0, reparse_tag: 0, @@ -425,7 +426,7 @@ impl File { self.handle.as_raw_handle(), c::FileStandardInfo, core::ptr::addr_of_mut!(info) as *mut c_void, - size as c::DWORD, + size as u32, ))?; attr.file_size = info.AllocationSize as u64; attr.number_of_links = Some(info.NumberOfLinks); @@ -495,7 +496,7 @@ impl File { SeekFrom::End(n) => (c::FILE_END, n), SeekFrom::Current(n) => (c::FILE_CURRENT, n), }; - let pos = pos as c::LARGE_INTEGER; + let pos = pos as i64; let mut newpos = 0; cvt(unsafe { c::SetFilePointerEx(self.handle.as_raw_handle(), pos, &mut newpos, whence) })?; Ok(newpos as u64) @@ -511,7 +512,7 @@ impl File { fn reparse_point( &self, space: &mut Align8<[MaybeUninit]>, - ) -> io::Result<(c::DWORD, *mut c::REPARSE_DATA_BUFFER)> { + ) -> io::Result<(u32, *mut c::REPARSE_DATA_BUFFER)> { unsafe { let mut bytes = 0; cvt({ @@ -524,7 +525,7 @@ impl File { ptr::null_mut(), 0, space.0.as_mut_ptr().cast(), - len as c::DWORD, + len as u32, &mut bytes, ptr::null_mut(), ) @@ -609,8 +610,7 @@ impl File { "Cannot set file timestamp to 0", )); } - let is_max = - |t: c::FILETIME| t.dwLowDateTime == c::DWORD::MAX && t.dwHighDateTime == c::DWORD::MAX; + let is_max = |t: c::FILETIME| t.dwLowDateTime == u32::MAX && t.dwHighDateTime == u32::MAX; if times.accessed.map_or(false, is_max) || times.modified.map_or(false, is_max) || times.created.map_or(false, is_max) @@ -641,7 +641,7 @@ impl File { self.handle.as_raw_handle(), c::FileBasicInfo, core::ptr::addr_of_mut!(info) as *mut c_void, - size as c::DWORD, + size as u32, ))?; Ok(info) } @@ -1020,7 +1020,7 @@ impl FileTimes { } impl FileType { - fn new(attrs: c::DWORD, reparse_tag: c::DWORD) -> FileType { + fn new(attrs: u32, reparse_tag: u32) -> FileType { FileType { attributes: attrs, reparse_tag } } pub fn is_dir(&self) -> bool { @@ -1417,16 +1417,16 @@ pub fn canonicalize(p: &Path) -> io::Result { pub fn copy(from: &Path, to: &Path) -> io::Result { unsafe extern "system" fn callback( - _TotalFileSize: c::LARGE_INTEGER, - _TotalBytesTransferred: c::LARGE_INTEGER, - _StreamSize: c::LARGE_INTEGER, - StreamBytesTransferred: c::LARGE_INTEGER, - dwStreamNumber: c::DWORD, - _dwCallbackReason: c::DWORD, + _TotalFileSize: i64, + _TotalBytesTransferred: i64, + _StreamSize: i64, + StreamBytesTransferred: i64, + dwStreamNumber: u32, + _dwCallbackReason: u32, _hSourceFile: c::HANDLE, _hDestinationFile: c::HANDLE, - lpData: c::LPCVOID, - ) -> c::DWORD { + lpData: *const c_void, + ) -> u32 { if dwStreamNumber == 1 { *(lpData as *mut i64) = StreamBytesTransferred; } diff --git a/library/std/src/sys/pal/windows/handle.rs b/library/std/src/sys/pal/windows/handle.rs index 3f85bb0a099a9..ae9ea8ff584ef 100644 --- a/library/std/src/sys/pal/windows/handle.rs +++ b/library/std/src/sys/pal/windows/handle.rs @@ -1,4 +1,5 @@ #![unstable(issue = "none", feature = "windows_handle")] +#![allow(unsafe_op_in_unsafe_fn)] #[cfg(test)] mod tests; @@ -141,7 +142,7 @@ impl Handle { buf: &mut [u8], overlapped: *mut c::OVERLAPPED, ) -> io::Result> { - let len = cmp::min(buf.len(), ::MAX as usize) as c::DWORD; + let len = cmp::min(buf.len(), u32::MAX as usize) as u32; let mut amt = 0; let res = cvt(c::ReadFile(self.as_raw_handle(), buf.as_mut_ptr(), len, &mut amt, overlapped)); @@ -209,12 +210,7 @@ impl Handle { Ok(Self(self.0.try_clone()?)) } - pub fn duplicate( - &self, - access: c::DWORD, - inherit: bool, - options: c::DWORD, - ) -> io::Result { + pub fn duplicate(&self, access: u32, inherit: bool, options: u32) -> io::Result { Ok(Self(self.0.as_handle().duplicate(access, inherit, options)?)) } @@ -233,7 +229,7 @@ impl Handle { let mut io_status = c::IO_STATUS_BLOCK::PENDING; // The length is clamped at u32::MAX. - let len = cmp::min(len, c::DWORD::MAX as usize) as c::DWORD; + let len = cmp::min(len, u32::MAX as usize) as u32; let status = c::NtReadFile( self.as_handle(), ptr::null_mut(), @@ -281,7 +277,7 @@ impl Handle { let mut io_status = c::IO_STATUS_BLOCK::PENDING; // The length is clamped at u32::MAX. - let len = cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD; + let len = cmp::min(buf.len(), u32::MAX as usize) as u32; let status = unsafe { c::NtWriteFile( self.as_handle(), diff --git a/library/std/src/sys/pal/windows/io.rs b/library/std/src/sys/pal/windows/io.rs index 77b8f3c410eb8..86d457db50a38 100644 --- a/library/std/src/sys/pal/windows/io.rs +++ b/library/std/src/sys/pal/windows/io.rs @@ -1,3 +1,4 @@ +#![allow(unsafe_op_in_unsafe_fn)] use crate::marker::PhantomData; use crate::mem::size_of; use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle}; @@ -15,9 +16,9 @@ pub struct IoSlice<'a> { impl<'a> IoSlice<'a> { #[inline] pub fn new(buf: &'a [u8]) -> IoSlice<'a> { - assert!(buf.len() <= c::ULONG::MAX as usize); + assert!(buf.len() <= u32::MAX as usize); IoSlice { - vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_ptr() as *mut u8 }, + vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_ptr() as *mut u8 }, _p: PhantomData, } } @@ -29,7 +30,7 @@ impl<'a> IoSlice<'a> { } unsafe { - self.vec.len -= n as c::ULONG; + self.vec.len -= n as u32; self.vec.buf = self.vec.buf.add(n); } } @@ -49,9 +50,9 @@ pub struct IoSliceMut<'a> { impl<'a> IoSliceMut<'a> { #[inline] pub fn new(buf: &'a mut [u8]) -> IoSliceMut<'a> { - assert!(buf.len() <= c::ULONG::MAX as usize); + assert!(buf.len() <= u32::MAX as usize); IoSliceMut { - vec: c::WSABUF { len: buf.len() as c::ULONG, buf: buf.as_mut_ptr() }, + vec: c::WSABUF { len: buf.len() as u32, buf: buf.as_mut_ptr() }, _p: PhantomData, } } @@ -63,7 +64,7 @@ impl<'a> IoSliceMut<'a> { } unsafe { - self.vec.len -= n as c::ULONG; + self.vec.len -= n as u32; self.vec.buf = self.vec.buf.add(n); } } diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 6406cec9c27d2..b85a8318bcbbd 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -1,4 +1,5 @@ #![allow(missing_docs, nonstandard_style)] +#![deny(unsafe_op_in_unsafe_fn)] use crate::ffi::{OsStr, OsString}; use crate::io::ErrorKind; @@ -54,11 +55,13 @@ impl IoResult for Result { // SAFETY: must be called only once during runtime initialization. // NOTE: this is not guaranteed to run, for example when Rust code is called externally. pub unsafe fn init(_argc: isize, _argv: *const *const u8, _sigpipe: u8) { - stack_overflow::init(); + unsafe { + stack_overflow::init(); - // Normally, `thread::spawn` will call `Thread::set_name` but since this thread already - // exists, we have to call it ourselves. - thread::Thread::set_name_wide(wide_str!("main")); + // Normally, `thread::spawn` will call `Thread::set_name` but since this thread already + // exists, we have to call it ourselves. + thread::Thread::set_name_wide(wide_str!("main")); + } } // SAFETY: must be called only once during runtime cleanup. @@ -75,7 +78,7 @@ pub fn is_interrupted(_errno: i32) -> bool { pub fn decode_error_kind(errno: i32) -> ErrorKind { use ErrorKind::*; - match errno as c::DWORD { + match errno as u32 { c::ERROR_ACCESS_DENIED => return PermissionDenied, c::ERROR_ALREADY_EXISTS => return AlreadyExists, c::ERROR_FILE_EXISTS => return AlreadyExists, @@ -216,7 +219,7 @@ pub fn to_u16s>(s: S) -> crate::io::Result> { // from this closure is then the return value of the function. pub fn fill_utf16_buf(mut f1: F1, f2: F2) -> crate::io::Result where - F1: FnMut(*mut u16, c::DWORD) -> c::DWORD, + F1: FnMut(*mut u16, u32) -> u32, F2: FnOnce(&[u16]) -> T, { // Start off with a stack buf but then spill over to the heap if we end up @@ -238,7 +241,7 @@ where // We used `reserve` and not `reserve_exact`, so in theory we // may have gotten more than requested. If so, we'd like to use // it... so long as we won't cause overflow. - n = heap_buf.capacity().min(c::DWORD::MAX as usize); + n = heap_buf.capacity().min(u32::MAX as usize); // Safety: MaybeUninit does not need initialization heap_buf.set_len(n); &mut heap_buf[..] @@ -254,13 +257,13 @@ where // error" is still 0 then we interpret it as a 0 length buffer and // not an actual error. c::SetLastError(0); - let k = match f1(buf.as_mut_ptr().cast::(), n as c::DWORD) { + let k = match f1(buf.as_mut_ptr().cast::(), n as u32) { 0 if api::get_last_error().code == 0 => 0, 0 => return Err(crate::io::Error::last_os_error()), n => n, } as usize; if k == n && api::get_last_error().code == c::ERROR_INSUFFICIENT_BUFFER { - n = n.saturating_mul(2).min(c::DWORD::MAX as usize); + n = n.saturating_mul(2).min(u32::MAX as usize); } else if k > n { n = k; } else if k == n { @@ -308,7 +311,7 @@ pub fn cvt(i: I) -> crate::io::Result { if i.is_zero() { Err(crate::io::Error::last_os_error()) } else { Ok(i) } } -pub fn dur2timeout(dur: Duration) -> c::DWORD { +pub fn dur2timeout(dur: Duration) -> u32 { // Note that a duration is a (u64, u32) (seconds, nanoseconds) pair, and the // timeouts in windows APIs are typically u32 milliseconds. To translate, we // have two pieces to take care of: @@ -320,7 +323,7 @@ pub fn dur2timeout(dur: Duration) -> c::DWORD { .checked_mul(1000) .and_then(|ms| ms.checked_add((dur.subsec_nanos() as u64) / 1_000_000)) .and_then(|ms| ms.checked_add(if dur.subsec_nanos() % 1_000_000 > 0 { 1 } else { 0 })) - .map(|ms| if ms > ::MAX as u64 { c::INFINITE } else { ms as c::DWORD }) + .map(|ms| if ms > ::MAX as u64 { c::INFINITE } else { ms as u32 }) .unwrap_or(c::INFINITE) } diff --git a/library/std/src/sys/pal/windows/net.rs b/library/std/src/sys/pal/windows/net.rs index 9e15b15a3513a..d51fb56238f2c 100644 --- a/library/std/src/sys/pal/windows/net.rs +++ b/library/std/src/sys/pal/windows/net.rs @@ -250,7 +250,7 @@ impl Socket { pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { // On unix when a socket is shut down all further reads return 0, so we // do the same on windows to map a shut down socket to returning EOF. - let length = cmp::min(bufs.len(), c::DWORD::MAX as usize) as c::DWORD; + let length = cmp::min(bufs.len(), u32::MAX as usize) as u32; let mut nread = 0; let mut flags = 0; let result = unsafe { @@ -335,7 +335,7 @@ impl Socket { } pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { - let length = cmp::min(bufs.len(), c::DWORD::MAX as usize) as c::DWORD; + let length = cmp::min(bufs.len(), u32::MAX as usize) as u32; let mut nwritten = 0; let result = unsafe { c::WSASend( @@ -371,7 +371,7 @@ impl Socket { } pub fn timeout(&self, kind: c_int) -> io::Result> { - let raw: c::DWORD = net::getsockopt(self, c::SOL_SOCKET, kind)?; + let raw: u32 = net::getsockopt(self, c::SOL_SOCKET, kind)?; if raw == 0 { Ok(None) } else { @@ -436,7 +436,7 @@ impl Socket { pub unsafe fn from_raw(raw: c::SOCKET) -> Self { debug_assert_eq!(mem::size_of::(), mem::size_of::()); debug_assert_eq!(mem::align_of::(), mem::align_of::()); - Self::from_raw_socket(raw as RawSocket) + unsafe { Self::from_raw_socket(raw as RawSocket) } } } @@ -486,6 +486,6 @@ impl IntoRawSocket for Socket { impl FromRawSocket for Socket { unsafe fn from_raw_socket(raw_socket: RawSocket) -> Self { - Self(FromRawSocket::from_raw_socket(raw_socket)) + unsafe { Self(FromRawSocket::from_raw_socket(raw_socket)) } } } diff --git a/library/std/src/sys/pal/windows/os.rs b/library/std/src/sys/pal/windows/os.rs index 62199c16bfed3..0a9279e50ba15 100644 --- a/library/std/src/sys/pal/windows/os.rs +++ b/library/std/src/sys/pal/windows/os.rs @@ -1,6 +1,7 @@ //! Implementation of `std::os` functionality for Windows. #![allow(nonstandard_style)] +#![allow(unsafe_op_in_unsafe_fn)] #[cfg(test)] mod tests; @@ -52,10 +53,10 @@ pub fn error_string(mut errnum: i32) -> String { let res = c::FormatMessageW( flags | c::FORMAT_MESSAGE_FROM_SYSTEM | c::FORMAT_MESSAGE_IGNORE_INSERTS, module, - errnum as c::DWORD, + errnum as u32, 0, buf.as_mut_ptr(), - buf.len() as c::DWORD, + buf.len() as u32, ptr::null(), ) as usize; if res == 0 { @@ -81,7 +82,7 @@ pub fn error_string(mut errnum: i32) -> String { } pub struct Env { - base: c::LPWCH, + base: *mut c::WCHAR, iter: EnvIterator, } @@ -126,7 +127,7 @@ impl Iterator for Env { } #[derive(Clone)] -struct EnvIterator(c::LPWCH); +struct EnvIterator(*mut c::WCHAR); impl Iterator for EnvIterator { type Item = (OsString, OsString); @@ -383,7 +384,7 @@ pub fn home_dir() -> Option { } pub fn exit(code: i32) -> ! { - unsafe { c::ExitProcess(code as c::UINT) } + unsafe { c::ExitProcess(code as u32) } } pub fn getpid() -> u32 { diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs index 67ef3ca82da02..d8b785f027c76 100644 --- a/library/std/src/sys/pal/windows/pipe.rs +++ b/library/std/src/sys/pal/windows/pipe.rs @@ -1,3 +1,4 @@ +#![allow(unsafe_op_in_unsafe_fn)] use crate::os::windows::prelude::*; use crate::ffi::OsStr; @@ -156,7 +157,7 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res opts.share_mode(0); let size = mem::size_of::(); let mut sa = c::SECURITY_ATTRIBUTES { - nLength: size as c::DWORD, + nLength: size as u32, lpSecurityDescriptor: ptr::null_mut(), bInheritHandle: their_handle_inheritable as i32, }; @@ -225,9 +226,9 @@ fn random_number() -> usize { // Abstracts over `ReadFileEx` and `WriteFileEx` type AlertableIoFn = unsafe extern "system" fn( BorrowedHandle<'_>, - c::LPVOID, - c::DWORD, - c::LPOVERLAPPED, + *mut core::ffi::c_void, + u32, + *mut c::OVERLAPPED, c::LPOVERLAPPED_COMPLETION_ROUTINE, ) -> c::BOOL; @@ -244,7 +245,7 @@ impl AnonPipe { pub fn read(&self, buf: &mut [u8]) -> io::Result { let result = unsafe { - let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD; + let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32; self.alertable_io_internal(c::ReadFileEx, buf.as_mut_ptr() as _, len) }; @@ -260,7 +261,7 @@ impl AnonPipe { pub fn read_buf(&self, mut buf: BorrowedCursor<'_>) -> io::Result<()> { let result = unsafe { - let len = crate::cmp::min(buf.capacity(), c::DWORD::MAX as usize) as c::DWORD; + let len = crate::cmp::min(buf.capacity(), u32::MAX as usize) as u32; self.alertable_io_internal(c::ReadFileEx, buf.as_mut().as_mut_ptr() as _, len) }; @@ -295,7 +296,7 @@ impl AnonPipe { pub fn write(&self, buf: &[u8]) -> io::Result { unsafe { - let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD; + let len = crate::cmp::min(buf.len(), u32::MAX as usize) as u32; self.alertable_io_internal(c::WriteFileEx, buf.as_ptr() as _, len) } } @@ -327,8 +328,8 @@ impl AnonPipe { unsafe fn alertable_io_internal( &self, io: AlertableIoFn, - buf: c::LPVOID, - len: c::DWORD, + buf: *mut core::ffi::c_void, + len: u32, ) -> io::Result { // Use "alertable I/O" to synchronize the pipe I/O. // This has four steps. diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs index c62764696b86b..76d2cb77d474c 100644 --- a/library/std/src/sys/pal/windows/process.rs +++ b/library/std/src/sys/pal/windows/process.rs @@ -19,7 +19,7 @@ use crate::path::{Path, PathBuf}; use crate::ptr; use crate::sync::Mutex; use crate::sys::args::{self, Arg}; -use crate::sys::c::{self, NonZeroDWORD, EXIT_FAILURE, EXIT_SUCCESS}; +use crate::sys::c::{self, EXIT_FAILURE, EXIT_SUCCESS}; use crate::sys::cvt; use crate::sys::fs::{File, OpenOptions}; use crate::sys::handle::Handle; @@ -174,7 +174,7 @@ pub struct Command { pub enum Stdio { Inherit, - InheritSpecific { from_stdio_id: c::DWORD }, + InheritSpecific { from_stdio_id: u32 }, Null, MakePipe, Pipe(AnonPipe), @@ -364,7 +364,7 @@ impl Command { }; si_ptr = core::ptr::addr_of_mut!(si_ex) as _; } else { - si.cb = mem::size_of::() as c::DWORD; + si.cb = mem::size_of::() as u32; si_ptr = core::ptr::addr_of_mut!(si) as _; } @@ -566,7 +566,7 @@ fn program_exists(path: &Path) -> Option> { } impl Stdio { - fn to_handle(&self, stdio_id: c::DWORD, pipe: &mut Option) -> io::Result { + fn to_handle(&self, stdio_id: u32, pipe: &mut Option) -> io::Result { let use_stdio_id = |stdio_id| match stdio::get_handle(stdio_id) { Ok(io) => unsafe { let io = Handle::from_raw_handle(io); @@ -601,7 +601,7 @@ impl Stdio { Stdio::Null => { let size = mem::size_of::(); let mut sa = c::SECURITY_ATTRIBUTES { - nLength: size as c::DWORD, + nLength: size as u32, lpSecurityDescriptor: ptr::null_mut(), bInheritHandle: 1, }; @@ -713,11 +713,11 @@ impl Process { } #[derive(PartialEq, Eq, Clone, Copy, Debug, Default)] -pub struct ExitStatus(c::DWORD); +pub struct ExitStatus(u32); impl ExitStatus { pub fn exit_ok(&self) -> Result<(), ExitStatusError> { - match NonZeroDWORD::try_from(self.0) { + match NonZero::::try_from(self.0) { /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)), /* was zero, couldn't convert */ Err(_) => Ok(()), } @@ -727,9 +727,9 @@ impl ExitStatus { } } -/// Converts a raw `c::DWORD` to a type-safe `ExitStatus` by wrapping it without copying. -impl From for ExitStatus { - fn from(u: c::DWORD) -> ExitStatus { +/// Converts a raw `u32` to a type-safe `ExitStatus` by wrapping it without copying. +impl From for ExitStatus { + fn from(u: u32) -> ExitStatus { ExitStatus(u) } } @@ -750,7 +750,7 @@ impl fmt::Display for ExitStatus { } #[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct ExitStatusError(c::NonZeroDWORD); +pub struct ExitStatusError(NonZero); impl Into for ExitStatusError { fn into(self) -> ExitStatus { @@ -765,7 +765,7 @@ impl ExitStatusError { } #[derive(PartialEq, Eq, Clone, Copy, Debug)] -pub struct ExitCode(c::DWORD); +pub struct ExitCode(u32); impl ExitCode { pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _); @@ -779,13 +779,13 @@ impl ExitCode { impl From for ExitCode { fn from(code: u8) -> Self { - ExitCode(c::DWORD::from(code)) + ExitCode(u32::from(code)) } } impl From for ExitCode { fn from(code: u32) -> Self { - ExitCode(c::DWORD::from(code)) + ExitCode(u32::from(code)) } } diff --git a/library/std/src/sys/pal/windows/rand.rs b/library/std/src/sys/pal/windows/rand.rs index 09f527a09bf12..e366bb995626a 100644 --- a/library/std/src/sys/pal/windows/rand.rs +++ b/library/std/src/sys/pal/windows/rand.rs @@ -20,7 +20,7 @@ pub fn hashmap_random_keys() -> (u64, u64) { let mut v = (0, 0); let ret = unsafe { - c::RtlGenRandom(ptr::addr_of_mut!(v).cast::(), mem::size_of_val(&v) as c::ULONG) + c::RtlGenRandom(ptr::addr_of_mut!(v).cast::(), mem::size_of_val(&v) as u32) }; if ret != 0 { v } else { panic!("RNG broken: {}", io::Error::last_os_error()) } diff --git a/library/std/src/sys/pal/windows/stack_overflow.rs b/library/std/src/sys/pal/windows/stack_overflow.rs index f93f31026f818..ea89429cb83cc 100644 --- a/library/std/src/sys/pal/windows/stack_overflow.rs +++ b/library/std/src/sys/pal/windows/stack_overflow.rs @@ -1,4 +1,5 @@ #![cfg_attr(test, allow(dead_code))] +#![allow(unsafe_op_in_unsafe_fn)] use crate::sys::c; use crate::thread; @@ -11,7 +12,7 @@ pub unsafe fn reserve_stack() { debug_assert_ne!(result, 0, "failed to reserve stack space for exception handling"); } -unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> c::LONG { +unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> i32 { unsafe { let rec = &(*(*ExceptionInfo).ExceptionRecord); let code = rec.ExceptionCode; diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs index 10aeeac07ea2e..c6a21665157d7 100644 --- a/library/std/src/sys/pal/windows/stdio.rs +++ b/library/std/src/sys/pal/windows/stdio.rs @@ -68,7 +68,7 @@ const MAX_BUFFER_SIZE: usize = 8192; // UTF-16 to UTF-8. pub const STDIN_BUF_SIZE: usize = MAX_BUFFER_SIZE / 2 * 3; -pub fn get_handle(handle_id: c::DWORD) -> io::Result { +pub fn get_handle(handle_id: u32) -> io::Result { let handle = unsafe { c::GetStdHandle(handle_id) }; if handle == c::INVALID_HANDLE_VALUE { Err(io::Error::last_os_error()) @@ -87,11 +87,7 @@ fn is_console(handle: c::HANDLE) -> bool { unsafe { c::GetConsoleMode(handle, &mut mode) != 0 } } -fn write( - handle_id: c::DWORD, - data: &[u8], - incomplete_utf8: &mut IncompleteUtf8, -) -> io::Result { +fn write(handle_id: u32, data: &[u8], incomplete_utf8: &mut IncompleteUtf8) -> io::Result { if data.is_empty() { return Ok(0); } @@ -182,12 +178,12 @@ fn write_valid_utf8_to_console(handle: c::HANDLE, utf8: &str) -> io::Result]) -> io::Result() as c::ULONG, + nLength: crate::mem::size_of::() as u32, nInitialChars: 0, dwCtrlWakeupMask: CTRL_Z_MASK, dwControlKeyState: 0, @@ -355,7 +351,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit]) -> io::Result]) -> io::Result io::Result { - debug_assert!(utf16.len() <= c::c_int::MAX as usize); - debug_assert!(utf8.len() <= c::c_int::MAX as usize); + debug_assert!(utf16.len() <= i32::MAX as usize); + debug_assert!(utf8.len() <= i32::MAX as usize); if utf16.is_empty() { return Ok(0); @@ -390,9 +386,9 @@ fn utf16_to_utf8(utf16: &[u16], utf8: &mut [u8]) -> io::Result { c::CP_UTF8, // CodePage c::WC_ERR_INVALID_CHARS, // dwFlags utf16.as_ptr(), // lpWideCharStr - utf16.len() as c::c_int, // cchWideChar + utf16.len() as i32, // cchWideChar utf8.as_mut_ptr(), // lpMultiByteStr - utf8.len() as c::c_int, // cbMultiByte + utf8.len() as i32, // cbMultiByte ptr::null(), // lpDefaultChar ptr::null_mut(), // lpUsedDefaultChar ) diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs index 70099e0a3b560..3648272a343a5 100644 --- a/library/std/src/sys/pal/windows/thread.rs +++ b/library/std/src/sys/pal/windows/thread.rs @@ -1,3 +1,4 @@ +#![allow(unsafe_op_in_unsafe_fn)] use crate::ffi::CStr; use crate::io; use crate::num::NonZero; @@ -45,7 +46,7 @@ impl Thread { Err(io::Error::last_os_error()) }; - unsafe extern "system" fn thread_start(main: *mut c_void) -> c::DWORD { + unsafe extern "system" fn thread_start(main: *mut c_void) -> u32 { // Next, reserve some stack space for if we otherwise run out of stack. stack_overflow::reserve_stack(); // Finally, let's run some code. diff --git a/library/std/src/sys/pal/windows/time.rs b/library/std/src/sys/pal/windows/time.rs index 09e78a29304f9..b853daeffebd7 100644 --- a/library/std/src/sys/pal/windows/time.rs +++ b/library/std/src/sys/pal/windows/time.rs @@ -76,8 +76,8 @@ impl SystemTime { fn from_intervals(intervals: i64) -> SystemTime { SystemTime { t: c::FILETIME { - dwLowDateTime: intervals as c::DWORD, - dwHighDateTime: (intervals >> 32) as c::DWORD, + dwLowDateTime: intervals as u32, + dwHighDateTime: (intervals >> 32) as u32, }, } } @@ -172,7 +172,7 @@ mod perf_counter { use crate::time::Duration; pub struct PerformanceCounterInstant { - ts: c::LARGE_INTEGER, + ts: i64, } impl PerformanceCounterInstant { pub fn now() -> Self { @@ -196,7 +196,7 @@ mod perf_counter { } } - fn frequency() -> c::LARGE_INTEGER { + fn frequency() -> i64 { // Either the cached result of `QueryPerformanceFrequency` or `0` for // uninitialized. Storing this as a single `AtomicU64` allows us to use // `Relaxed` operations, as we are only interested in the effects on a @@ -206,7 +206,7 @@ mod perf_counter { let cached = FREQUENCY.load(Ordering::Relaxed); // If a previous thread has filled in this global state, use that. if cached != 0 { - return cached as c::LARGE_INTEGER; + return cached as i64; } // ... otherwise learn for ourselves ... let mut frequency = 0; @@ -218,8 +218,8 @@ mod perf_counter { frequency } - fn query() -> c::LARGE_INTEGER { - let mut qpc_value: c::LARGE_INTEGER = 0; + fn query() -> i64 { + let mut qpc_value: i64 = 0; cvt(unsafe { c::QueryPerformanceCounter(&mut qpc_value) }).unwrap(); qpc_value } diff --git a/library/std/src/sys/sync/mutex/windows7.rs b/library/std/src/sys/sync/mutex/windows7.rs index ef2f84082cd5c..689dba10f01ed 100644 --- a/library/std/src/sys/sync/mutex/windows7.rs +++ b/library/std/src/sys/sync/mutex/windows7.rs @@ -25,7 +25,7 @@ unsafe impl Send for Mutex {} unsafe impl Sync for Mutex {} #[inline] -pub unsafe fn raw(m: &Mutex) -> c::PSRWLOCK { +pub unsafe fn raw(m: &Mutex) -> *mut c::SRWLOCK { m.srwlock.get() } diff --git a/library/std/src/sys/sync/thread_parking/windows.rs b/library/std/src/sys/sync/thread_parking/windows.rs index 4b8102d505a1f..3a8d40dc5cfac 100644 --- a/library/std/src/sys/sync/thread_parking/windows.rs +++ b/library/std/src/sys/sync/thread_parking/windows.rs @@ -64,6 +64,7 @@ use crate::sync::atomic::{ }; use crate::sys::{c, dur2timeout}; use crate::time::Duration; +use core::ffi::c_void; pub struct Parker { state: AtomicI8, @@ -117,7 +118,7 @@ impl Parker { loop { // Wait for something to happen, assuming it's still set to PARKED. - c::WaitOnAddress(self.ptr(), &PARKED as *const _ as c::LPVOID, 1, c::INFINITE); + c::WaitOnAddress(self.ptr(), &PARKED as *const _ as *const c_void, 1, c::INFINITE); // Change NOTIFIED=>EMPTY but leave PARKED alone. if self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Acquire).is_ok() { // Actually woken up by unpark(). @@ -144,7 +145,7 @@ impl Parker { } // Wait for something to happen, assuming it's still set to PARKED. - c::WaitOnAddress(self.ptr(), &PARKED as *const _ as c::LPVOID, 1, dur2timeout(timeout)); + c::WaitOnAddress(self.ptr(), &PARKED as *const _ as *const c_void, 1, dur2timeout(timeout)); // Set the state back to EMPTY (from either PARKED or NOTIFIED). // Note that we don't just write EMPTY, but use swap() to also // include an acquire-ordered read to synchronize with unpark()'s @@ -177,8 +178,8 @@ impl Parker { } } - fn ptr(&self) -> c::LPVOID { - core::ptr::addr_of!(self.state) as c::LPVOID + fn ptr(&self) -> *const c_void { + core::ptr::addr_of!(self.state).cast::() } } diff --git a/library/std/src/sys/thread_local/guard/windows.rs b/library/std/src/sys/thread_local/guard/windows.rs index 81797f55170d7..f6cd457046ffc 100644 --- a/library/std/src/sys/thread_local/guard/windows.rs +++ b/library/std/src/sys/thread_local/guard/windows.rs @@ -65,6 +65,7 @@ use crate::ptr; use crate::sys::c; +use core::ffi::c_void; pub fn enable() { // When destructors are used, we don't want LLVM eliminating CALLBACK for any @@ -74,9 +75,9 @@ pub fn enable() { #[link_section = ".CRT$XLB"] #[cfg_attr(miri, used)] // Miri only considers explicitly `#[used]` statics for `lookup_link_section` -pub static CALLBACK: unsafe extern "system" fn(c::LPVOID, c::DWORD, c::LPVOID) = tls_callback; +pub static CALLBACK: unsafe extern "system" fn(*mut c_void, u32, *mut c_void) = tls_callback; -unsafe extern "system" fn tls_callback(_h: c::LPVOID, dw_reason: c::DWORD, _pv: c::LPVOID) { +unsafe extern "system" fn tls_callback(_h: *mut c_void, dw_reason: u32, _pv: *mut c_void) { // See comments above for what this is doing. Note that we don't need this // trickery on GNU windows, just on MSVC. #[cfg(all(target_env = "msvc", not(target_thread_local)))] diff --git a/library/std/src/sys/thread_local/key/windows.rs b/library/std/src/sys/thread_local/key/windows.rs index baf23979c7c61..8b43e558d5d98 100644 --- a/library/std/src/sys/thread_local/key/windows.rs +++ b/library/std/src/sys/thread_local/key/windows.rs @@ -33,11 +33,11 @@ use crate::sync::atomic::{ use crate::sys::c; use crate::sys::thread_local::guard; -pub type Key = c::DWORD; +pub type Key = u32; type Dtor = unsafe extern "C" fn(*mut u8); pub struct LazyKey { - /// The key value shifted up by one. Since TLS_OUT_OF_INDEXES == DWORD::MAX + /// The key value shifted up by one. Since TLS_OUT_OF_INDEXES == u32::MAX /// is not a valid key value, this allows us to use zero as sentinel value /// without risking overflow. key: AtomicU32, diff --git a/library/std/src/sys_common/wtf8.rs b/library/std/src/sys_common/wtf8.rs index 117a3e23044ea..6aeeb6259285d 100644 --- a/library/std/src/sys_common/wtf8.rs +++ b/library/std/src/sys_common/wtf8.rs @@ -602,7 +602,8 @@ impl Wtf8 { /// marked unsafe. #[inline] pub unsafe fn from_bytes_unchecked(value: &[u8]) -> &Wtf8 { - mem::transmute(value) + // SAFETY: start with &[u8], end with fancy &[u8] + unsafe { &*(value as *const [u8] as *const Wtf8) } } /// Creates a mutable WTF-8 slice from a mutable WTF-8 byte slice. @@ -611,7 +612,8 @@ impl Wtf8 { /// marked unsafe. #[inline] unsafe fn from_mut_bytes_unchecked(value: &mut [u8]) -> &mut Wtf8 { - mem::transmute(value) + // SAFETY: start with &mut [u8], end with fancy &mut [u8] + unsafe { &mut *(value as *mut [u8] as *mut Wtf8) } } /// Returns the length, in WTF-8 bytes. @@ -942,8 +944,12 @@ pub fn check_utf8_boundary(slice: &Wtf8, index: usize) { /// Copied from core::str::raw::slice_unchecked #[inline] pub unsafe fn slice_unchecked(s: &Wtf8, begin: usize, end: usize) -> &Wtf8 { - // memory layout of a &[u8] and &Wtf8 are the same - Wtf8::from_bytes_unchecked(slice::from_raw_parts(s.bytes.as_ptr().add(begin), end - begin)) + // SAFETY: memory layout of a &[u8] and &Wtf8 are the same + unsafe { + let len = end - begin; + let start = s.as_bytes().as_ptr().add(begin); + Wtf8::from_bytes_unchecked(slice::from_raw_parts(start, len)) + } } /// Copied from core::str::raw::slice_error_fail diff --git a/src/tools/miri/tests/fail/alloc/global_system_mixup.rs b/src/tools/miri/tests/fail/alloc/global_system_mixup.rs index 2e88e5644e441..19c62913b4c66 100644 --- a/src/tools/miri/tests/fail/alloc/global_system_mixup.rs +++ b/src/tools/miri/tests/fail/alloc/global_system_mixup.rs @@ -4,7 +4,7 @@ //@normalize-stderr-test: "using [A-Za-z]+ heap deallocation operation" -> "using PLATFORM heap deallocation operation" //@normalize-stderr-test: "\| +\^+" -> "| ^" -//@normalize-stderr-test: "libc::free\([^()]*\)|unsafe \{ HeapFree\([^()]*\) \};" -> "FREE();" +//@normalize-stderr-test: "libc::free\([^()]*\)|unsafe \{ HeapFree\([^}]*\};" -> "FREE();" #![feature(allocator_api, slice_ptr_get)]