Enable unsafe_op_in_unsafe_fn and missing_unsafe_on_extern lints (#5557)

* Enable unsafe_op_in_unsafe_fn lint

* Enable missing_unsafe_on_extern lint

* Make PyObjectRef::{from,into}_raw() use NonNull
This commit is contained in:
Jeong, YunWon
2025-02-25 13:42:25 +09:00
committed by GitHub
32 changed files with 189 additions and 159 deletions

View File

@@ -189,6 +189,9 @@ wasm-bindgen = "0.2.100"
[workspace.lints.rust]
unsafe_code = "allow"
unsafe_op_in_unsafe_fn = "deny"
missing_unsafe_on_extern = "deny"
unsafe_attr_outside_unsafe = "deny"
[workspace.lints.clippy]
perf = "warn"

View File

@@ -87,13 +87,16 @@ impl<T> BoxVec<T> {
pub unsafe fn push_unchecked(&mut self, element: T) {
let len = self.len();
debug_assert!(len < self.capacity());
ptr::write(self.get_unchecked_ptr(len), element);
self.set_len(len + 1);
// SAFETY: len < capacity
unsafe {
ptr::write(self.get_unchecked_ptr(len), element);
self.set_len(len + 1);
}
}
/// Get pointer to where element at `index` would be
unsafe fn get_unchecked_ptr(&mut self, index: usize) -> *mut T {
self.xs.as_mut_ptr().add(index).cast()
unsafe { self.xs.as_mut_ptr().add(index).cast() }
}
pub fn insert(&mut self, index: usize, element: T) {
@@ -568,7 +571,7 @@ unsafe fn raw_ptr_add<T>(ptr: *mut T, offset: usize) -> *mut T {
// Special case for ZST
(ptr as usize).wrapping_add(offset) as _
} else {
ptr.add(offset)
unsafe { ptr.add(offset) }
}
}
@@ -576,7 +579,7 @@ unsafe fn raw_ptr_write<T>(ptr: *mut T, value: T) {
if mem::size_of::<T>() == 0 {
/* nothing */
} else {
ptr::write(ptr, value)
unsafe { ptr::write(ptr, value) }
}
}

View File

@@ -6,7 +6,7 @@ use std::{cmp, ffi, io};
#[cfg(windows)]
use libc::commit as fsync;
#[cfg(windows)]
extern "C" {
unsafe extern "C" {
#[link_name = "_chsize_s"]
fn ftruncate(fd: i32, len: i64) -> i32;
}
@@ -74,7 +74,7 @@ impl Fd {
#[cfg(windows)]
pub fn to_raw_handle(&self) -> io::Result<std::os::windows::io::RawHandle> {
extern "C" {
unsafe extern "C" {
fn _get_osfhandle(fd: i32) -> libc::intptr_t;
}
let handle = unsafe { suppress_iph!(_get_osfhandle(self.0)) };

View File

@@ -42,8 +42,8 @@ struct DecodeError<'a> {
/// # Safety
/// `v[..valid_up_to]` must be valid utf8
unsafe fn make_decode_err(v: &[u8], valid_up_to: usize, err_len: Option<usize>) -> DecodeError<'_> {
let valid_prefix = core::str::from_utf8_unchecked(v.get_unchecked(..valid_up_to));
let rest = v.get_unchecked(valid_up_to..);
let (valid_prefix, rest) = unsafe { v.split_at_unchecked(valid_up_to) };
let valid_prefix = unsafe { core::str::from_utf8_unchecked(valid_prefix) };
DecodeError {
valid_prefix,
rest,

View File

@@ -94,7 +94,7 @@ pub mod windows {
}
}
extern "C" {
unsafe extern "C" {
fn _get_osfhandle(fd: i32) -> libc::intptr_t;
}

View File

@@ -208,37 +208,39 @@ impl<L: Link> LinkedList<L, L::Target> {
/// The caller **must** ensure that `node` is currently contained by
/// `self` or not contained by any other list.
pub unsafe fn remove(&mut self, node: NonNull<L::Target>) -> Option<L::Handle> {
if let Some(prev) = L::pointers(node).as_ref().get_prev() {
debug_assert_eq!(L::pointers(prev).as_ref().get_next(), Some(node));
L::pointers(prev)
.as_mut()
.set_next(L::pointers(node).as_ref().get_next());
} else {
if self.head != Some(node) {
return None;
unsafe {
if let Some(prev) = L::pointers(node).as_ref().get_prev() {
debug_assert_eq!(L::pointers(prev).as_ref().get_next(), Some(node));
L::pointers(prev)
.as_mut()
.set_next(L::pointers(node).as_ref().get_next());
} else {
if self.head != Some(node) {
return None;
}
self.head = L::pointers(node).as_ref().get_next();
}
self.head = L::pointers(node).as_ref().get_next();
if let Some(next) = L::pointers(node).as_ref().get_next() {
debug_assert_eq!(L::pointers(next).as_ref().get_prev(), Some(node));
L::pointers(next)
.as_mut()
.set_prev(L::pointers(node).as_ref().get_prev());
} else {
// // This might be the last item in the list
// if self.tail != Some(node) {
// return None;
// }
// self.tail = L::pointers(node).as_ref().get_prev();
}
L::pointers(node).as_mut().set_next(None);
L::pointers(node).as_mut().set_prev(None);
Some(L::from_raw(node))
}
if let Some(next) = L::pointers(node).as_ref().get_next() {
debug_assert_eq!(L::pointers(next).as_ref().get_prev(), Some(node));
L::pointers(next)
.as_mut()
.set_prev(L::pointers(node).as_ref().get_prev());
} else {
// // This might be the last item in the list
// if self.tail != Some(node) {
// return None;
// }
// self.tail = L::pointers(node).as_ref().get_prev();
}
L::pointers(node).as_mut().set_next(None);
L::pointers(node).as_mut().set_prev(None);
Some(L::from_raw(node))
}
// pub fn last(&self) -> Option<&L::Target> {

View File

@@ -140,12 +140,12 @@ unsafe impl RawRwLockUpgrade for RawCellRwLock {
#[inline]
unsafe fn unlock_upgradable(&self) {
self.unlock_shared()
unsafe { self.unlock_shared() }
}
#[inline]
unsafe fn upgrade(&self) {
if !self.try_upgrade() {
if !unsafe { self.try_upgrade() } {
deadlock("upgrade ", "RwLock")
}
}

View File

@@ -65,7 +65,7 @@ impl<R: RawMutex, G: GetThreadId> RawThreadMutex<R, G> {
/// This method may only be called if the mutex is held by the current thread.
pub unsafe fn unlock(&self) {
self.owner.store(0, Ordering::Relaxed);
self.mutex.unlock();
unsafe { self.mutex.unlock() };
}
}

View File

@@ -41,7 +41,7 @@ pub mod __macro_private {
libc::uintptr_t,
);
#[cfg(target_env = "msvc")]
extern "C" {
unsafe extern "C" {
pub fn _set_thread_local_invalid_parameter_handler(
pNew: InvalidParamHandler,
) -> InvalidParamHandler;

View File

@@ -23,7 +23,7 @@ pub fn last_os_error() -> io::Error {
let err = io::Error::last_os_error();
// FIXME: probably not ideal, we need a bigger dichotomy between GetLastError and errno
if err.raw_os_error() == Some(0) {
extern "C" {
unsafe extern "C" {
fn _get_errno(pValue: *mut i32) -> i32;
}
let mut errno = 0;
@@ -44,7 +44,7 @@ pub fn last_os_error() -> io::Error {
pub fn last_posix_errno() -> i32 {
let err = io::Error::last_os_error();
if err.raw_os_error() == Some(0) {
extern "C" {
unsafe extern "C" {
fn _get_errno(pValue: *mut i32) -> i32;
}
let mut errno = 0;

View File

@@ -293,10 +293,8 @@ impl<T: OpArgType> Arg<T> {
/// # Safety
/// T::from_op_arg(self) must succeed
pub unsafe fn get_unchecked(self, arg: OpArg) -> T {
match T::from_op_arg(arg.0) {
Some(t) => t,
None => std::hint::unreachable_unchecked(),
}
// SAFETY: requirements forwarded from caller
unsafe { T::from_op_arg(arg.0).unwrap_unchecked() }
}
}

View File

@@ -152,12 +152,14 @@ impl CompiledCode {
}
unsafe fn invoke_raw(&self, cif_args: &[libffi::middle::Arg]) -> Option<AbiValue> {
let cif = self.sig.to_cif();
let value = cif.call::<UnTypedAbiValue>(
libffi::middle::CodePtr::from_ptr(self.code as *const _),
cif_args,
);
self.sig.ret.as_ref().map(|ty| value.to_typed(ty))
unsafe {
let cif = self.sig.to_cif();
let value = cif.call::<UnTypedAbiValue>(
libffi::middle::CodePtr::from_ptr(self.code as *const _),
cif_args,
);
self.sig.ret.as_ref().map(|ty| value.to_typed(ty))
}
}
}
@@ -290,10 +292,12 @@ union UnTypedAbiValue {
impl UnTypedAbiValue {
unsafe fn to_typed(self, ty: &JitType) -> AbiValue {
match ty {
JitType::Int => AbiValue::Int(self.int),
JitType::Float => AbiValue::Float(self.float),
JitType::Bool => AbiValue::Bool(self.boolean != 0),
unsafe {
match ty {
JitType::Int => AbiValue::Int(self.int),
JitType::Float => AbiValue::Float(self.float),
JitType::Bool => AbiValue::Bool(self.boolean != 0),
}
}
}
}

View File

@@ -78,7 +78,7 @@ pub fn run(init: impl FnOnce(&mut VirtualMachine) + 'static) -> ExitCode {
// don't translate newlines (\r\n <=> \n)
#[cfg(windows)]
{
extern "C" {
unsafe extern "C" {
fn _setmode(fd: i32, flags: i32) -> i32;
}
unsafe {

View File

@@ -30,7 +30,7 @@ struct lconv {
}
#[cfg(windows)]
extern "C" {
unsafe extern "C" {
fn localeconv() -> *mut lconv;
}
@@ -78,11 +78,13 @@ mod _locale {
return vm.ctx.new_list(group_vec);
}
let mut ptr = group;
while ![0, libc::c_char::MAX].contains(&*ptr) {
let val = vm.ctx.new_int(*ptr);
group_vec.push(val.into());
ptr = ptr.add(1);
unsafe {
let mut ptr = group;
while ![0, libc::c_char::MAX].contains(&*ptr) {
let val = vm.ctx.new_int(*ptr);
group_vec.push(val.into());
ptr = ptr.add(1);
}
}
// https://github.com/python/cpython/blob/677320348728ce058fa3579017e985af74a236d4/Modules/_localemodule.c#L80
if !group_vec.is_empty() {

View File

@@ -36,28 +36,30 @@ mod platform {
// based off winsock2.h: https://gist.github.com/piscisaureus/906386#file-winsock2-h-L128-L141
pub unsafe fn FD_SET(fd: RawFd, set: *mut fd_set) {
let mut slot = (&raw mut (*set).fd_array).cast::<RawFd>();
let fd_count = (*set).fd_count;
for _ in 0..fd_count {
if *slot == fd {
return;
unsafe {
let mut slot = (&raw mut (*set).fd_array).cast::<RawFd>();
let fd_count = (*set).fd_count;
for _ in 0..fd_count {
if *slot == fd {
return;
}
slot = slot.add(1);
}
// slot == &fd_array[fd_count] at this point
if fd_count < FD_SETSIZE {
*slot = fd as RawFd;
(*set).fd_count += 1;
}
slot = slot.add(1);
}
// slot == &fd_array[fd_count] at this point
if fd_count < FD_SETSIZE {
*slot = fd as RawFd;
(*set).fd_count += 1;
}
}
pub unsafe fn FD_ZERO(set: *mut fd_set) {
(*set).fd_count = 0;
unsafe { (*set).fd_count = 0 };
}
pub unsafe fn FD_ISSET(fd: RawFd, set: *mut fd_set) -> bool {
use WinSock::__WSAFDIsSet;
__WSAFDIsSet(fd as _, set) != 0
unsafe { __WSAFDIsSet(fd as _, set) != 0 }
}
pub fn check_err(x: i32) -> bool {
@@ -82,7 +84,7 @@ mod platform {
#[allow(non_snake_case)]
pub unsafe fn FD_ISSET(fd: RawFd, set: *const fd_set) -> bool {
let set = &*set;
let set = unsafe { &*set };
let n = set.__nfds;
for p in &set.__fds[..n] {
if *p == fd {
@@ -94,7 +96,7 @@ mod platform {
#[allow(non_snake_case)]
pub unsafe fn FD_SET(fd: RawFd, set: *mut fd_set) {
let set = &mut *set;
let set = unsafe { &mut *set };
let n = set.__nfds;
for p in &set.__fds[..n] {
if *p == fd {
@@ -107,11 +109,11 @@ mod platform {
#[allow(non_snake_case)]
pub unsafe fn FD_ZERO(set: *mut fd_set) {
let set = &mut *set;
let set = unsafe { &mut *set };
set.__nfds = 0;
}
extern "C" {
unsafe extern "C" {
pub fn select(
nfds: libc::c_int,
readfds: *mut fd_set,

View File

@@ -1788,7 +1788,7 @@ mod _socket {
}
unsafe fn slice_as_uninit<T>(v: &mut [T]) -> &mut [MaybeUninit<T>] {
&mut *(v as *mut [T] as *mut [MaybeUninit<T>])
unsafe { &mut *(v as *mut [T] as *mut [MaybeUninit<T>]) }
}
enum IoOrPyException {
@@ -2312,12 +2312,12 @@ mod _socket {
#[cfg(unix)]
{
use std::os::unix::io::FromRawFd;
Socket::from_raw_fd(fileno)
unsafe { Socket::from_raw_fd(fileno) }
}
#[cfg(windows)]
{
use std::os::windows::io::FromRawSocket;
Socket::from_raw_socket(fileno)
unsafe { Socket::from_raw_socket(fileno) }
}
}
pub(super) fn sock_fileno(sock: &Socket) -> RawSocket {

View File

@@ -76,7 +76,7 @@ mod _sqlite {
ffi::{c_int, c_longlong, c_uint, c_void, CStr},
fmt::Debug,
ops::Deref,
ptr::{null, null_mut},
ptr::{null, null_mut, NonNull},
thread::ThreadId,
};
@@ -381,7 +381,7 @@ mod _sqlite {
}
struct CallbackData {
obj: *const PyObject,
obj: NonNull<PyObject>,
vm: *const VirtualMachine,
}
@@ -394,11 +394,11 @@ mod _sqlite {
}
fn retrieve(&self) -> (&PyObject, &VirtualMachine) {
unsafe { (&*self.obj, &*self.vm) }
unsafe { (self.obj.as_ref(), &*self.vm) }
}
unsafe extern "C" fn destructor(data: *mut c_void) {
drop(Box::from_raw(data.cast::<Self>()));
drop(unsafe { Box::from_raw(data.cast::<Self>()) });
}
unsafe extern "C" fn func_callback(
@@ -407,8 +407,8 @@ mod _sqlite {
argv: *mut *mut sqlite3_value,
) {
let context = SqliteContext::from(context);
let (func, vm) = (*context.user_data::<Self>()).retrieve();
let args = std::slice::from_raw_parts(argv, argc as usize);
let (func, vm) = unsafe { (*context.user_data::<Self>()).retrieve() };
let args = unsafe { std::slice::from_raw_parts(argv, argc as usize) };
let f = || -> PyResult<()> {
let db = context.db_handle();
@@ -434,12 +434,12 @@ mod _sqlite {
argv: *mut *mut sqlite3_value,
) {
let context = SqliteContext::from(context);
let (cls, vm) = (*context.user_data::<Self>()).retrieve();
let args = std::slice::from_raw_parts(argv, argc as usize);
let (cls, vm) = unsafe { (*context.user_data::<Self>()).retrieve() };
let args = unsafe { std::slice::from_raw_parts(argv, argc as usize) };
let instance = context.aggregate_context::<*const PyObject>();
if (*instance).is_null() {
if unsafe { (*instance).is_null() } {
match cls.call((), vm) {
Ok(obj) => *instance = obj.into_raw(),
Ok(obj) => unsafe { *instance = obj.into_raw().as_ptr() },
Err(exc) => {
return context.result_exception(
vm,
@@ -449,16 +449,16 @@ mod _sqlite {
}
}
}
let instance = &**instance;
let instance = unsafe { &**instance };
Self::call_method_with_args(context, instance, "step", args, vm);
}
unsafe extern "C" fn finalize_callback(context: *mut sqlite3_context) {
let context = SqliteContext::from(context);
let (_, vm) = (*context.user_data::<Self>()).retrieve();
let (_, vm) = unsafe { (*context.user_data::<Self>()).retrieve() };
let instance = context.aggregate_context::<*const PyObject>();
let Some(instance) = (*instance).as_ref() else {
let Some(instance) = (unsafe { (*instance).as_ref() }) else {
return;
};
@@ -472,7 +472,7 @@ mod _sqlite {
b_len: c_int,
b_ptr: *const c_void,
) -> c_int {
let (callable, vm) = (*data.cast::<Self>()).retrieve();
let (callable, vm) = unsafe { (*data.cast::<Self>()).retrieve() };
let f = || -> PyResult<c_int> {
let text1 = ptr_to_string(a_ptr.cast(), a_len, null_mut(), vm)?;
@@ -499,9 +499,9 @@ mod _sqlite {
unsafe extern "C" fn value_callback(context: *mut sqlite3_context) {
let context = SqliteContext::from(context);
let (_, vm) = (*context.user_data::<Self>()).retrieve();
let (_, vm) = unsafe { (*context.user_data::<Self>()).retrieve() };
let instance = context.aggregate_context::<*const PyObject>();
let instance = &**instance;
let instance = unsafe { &**instance };
Self::callback_result_from_method(context, instance, "value", vm);
}
@@ -512,10 +512,10 @@ mod _sqlite {
argv: *mut *mut sqlite3_value,
) {
let context = SqliteContext::from(context);
let (_, vm) = (*context.user_data::<Self>()).retrieve();
let args = std::slice::from_raw_parts(argv, argc as usize);
let (_, vm) = unsafe { (*context.user_data::<Self>()).retrieve() };
let args = unsafe { std::slice::from_raw_parts(argv, argc as usize) };
let instance = context.aggregate_context::<*const PyObject>();
let instance = &**instance;
let instance = unsafe { &**instance };
Self::call_method_with_args(context, instance, "inverse", args, vm);
}
@@ -528,7 +528,7 @@ mod _sqlite {
db_name: *const libc::c_char,
access: *const libc::c_char,
) -> c_int {
let (callable, vm) = (*data.cast::<Self>()).retrieve();
let (callable, vm) = unsafe { (*data.cast::<Self>()).retrieve() };
let f = || -> PyResult<c_int> {
let arg1 = ptr_to_str(arg1, vm)?;
let arg2 = ptr_to_str(arg2, vm)?;
@@ -551,8 +551,8 @@ mod _sqlite {
stmt: *mut c_void,
sql: *mut c_void,
) -> c_int {
let (callable, vm) = (*data.cast::<Self>()).retrieve();
let expanded = sqlite3_expanded_sql(stmt.cast());
let (callable, vm) = unsafe { (*data.cast::<Self>()).retrieve() };
let expanded = unsafe { sqlite3_expanded_sql(stmt.cast()) };
let f = || -> PyResult<()> {
let stmt = ptr_to_str(expanded, vm).or_else(|_| ptr_to_str(sql.cast(), vm))?;
callable.call((stmt,), vm)?;
@@ -563,7 +563,7 @@ mod _sqlite {
}
unsafe extern "C" fn progress_callback(data: *mut c_void) -> c_int {
let (callable, vm) = (*data.cast::<Self>()).retrieve();
let (callable, vm) = unsafe { (*data.cast::<Self>()).retrieve() };
if let Ok(val) = callable.call((), vm) {
if let Ok(val) = val.is_true(vm) {
return val as c_int;

View File

@@ -4,7 +4,8 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
// if openssl is vendored, it doesn't know the locations of system certificates
#[cfg(feature = "ssl-vendor")]
if let None | Some("0") = option_env!("OPENSSL_NO_VENDOR") {
openssl_probe::init_ssl_cert_env_vars();
// TODO: use openssl_probe::probe() instead
unsafe { openssl_probe::init_openssl_env_vars() };
}
openssl::init();
_ssl::make_module(vm)
@@ -283,7 +284,7 @@ mod _ssl {
if ptr.is_null() {
None
} else {
Some(Asn1Object::from_ptr(ptr))
Some(unsafe { Asn1Object::from_ptr(ptr) })
}
}

View File

@@ -313,7 +313,7 @@ impl PyStr {
/// # Safety
/// Given `bytes` must be ascii
pub unsafe fn new_ascii_unchecked(bytes: Vec<u8>) -> Self {
Self::new_str_unchecked(bytes, PyStrKind::Ascii)
unsafe { Self::new_str_unchecked(bytes, PyStrKind::Ascii) }
}
pub fn new_ref(zelf: impl Into<Self>, ctx: &Context) -> PyRef<Self> {

View File

@@ -69,7 +69,7 @@ pub struct PointerSlot<T>(NonNull<T>);
impl<T> PointerSlot<T> {
pub unsafe fn borrow_static(&self) -> &'static T {
self.0.as_ref()
unsafe { self.0.as_ref() }
}
}

View File

@@ -274,7 +274,7 @@ impl HeapMethodDef {
impl Py<HeapMethodDef> {
pub(crate) unsafe fn method(&self) -> &'static PyMethodDef {
&*(&self.method as *const _)
unsafe { &*(&self.method as *const _) }
}
pub fn build_function(&self, vm: &VirtualMachine) -> PyRef<PyNativeFunction> {

View File

@@ -117,7 +117,7 @@ impl CachedPyStrRef {
/// the given cache must be alive while returned reference is alive
#[inline]
unsafe fn as_interned_str(&self) -> &'static PyStrInterned {
std::mem::transmute_copy(self)
unsafe { std::mem::transmute_copy(self) }
}
#[inline]

View File

@@ -77,19 +77,19 @@ use std::{
pub(super) struct Erased;
pub(super) unsafe fn drop_dealloc_obj<T: PyObjectPayload>(x: *mut PyObject) {
drop(Box::from_raw(x as *mut PyInner<T>));
drop(unsafe { Box::from_raw(x as *mut PyInner<T>) });
}
pub(super) unsafe fn debug_obj<T: PyObjectPayload>(
x: &PyObject,
f: &mut fmt::Formatter,
) -> fmt::Result {
let x = &*(x as *const PyObject as *const PyInner<T>);
let x = unsafe { &*(x as *const PyObject as *const PyInner<T>) };
fmt::Debug::fmt(x, f)
}
/// Call `try_trace` on payload
pub(super) unsafe fn try_trace_obj<T: PyObjectPayload>(x: &PyObject, tracer_fn: &mut TraverseFn) {
let x = &*(x as *const PyObject as *const PyInner<T>);
let x = unsafe { &*(x as *const PyObject as *const PyInner<T>) };
let payload = &x.payload;
payload.try_traverse(tracer_fn)
}
@@ -278,7 +278,7 @@ impl WeakRefList {
}
unsafe fn dealloc(ptr: NonNull<PyMutex<WeakListInner>>) {
drop(Box::from_raw(ptr.as_ptr()));
drop(unsafe { Box::from_raw(ptr.as_ptr()) });
}
fn get_weak_references(&self) -> Vec<PyRef<PyWeak>> {
@@ -317,12 +317,14 @@ unsafe impl Link for WeakLink {
#[inline(always)]
unsafe fn from_raw(ptr: NonNull<Self::Target>) -> Self::Handle {
PyRef::from_raw(ptr.as_ptr())
// SAFETY: requirements forwarded from caller
unsafe { PyRef::from_raw(ptr.as_ptr()) }
}
#[inline(always)]
unsafe fn pointers(target: NonNull<Self::Target>) -> NonNull<Pointers<Self::Target>> {
NonNull::new_unchecked(&raw mut (*target.as_ptr()).0.payload.pointers)
// SAFETY: requirements forwarded from caller
unsafe { NonNull::new_unchecked(&raw mut (*target.as_ptr()).0.payload.pointers) }
}
}
@@ -352,7 +354,7 @@ impl PyWeak {
if !obj_ptr.as_ref().0.ref_count.safe_inc() {
return None;
}
Some(PyObjectRef::from_raw(obj_ptr.as_ptr()))
Some(PyObjectRef::from_raw(obj_ptr))
}
}
@@ -506,8 +508,8 @@ impl ToOwned for PyObject {
impl PyObjectRef {
#[inline(always)]
pub fn into_raw(self) -> *const PyObject {
let ptr = self.as_raw();
pub fn into_raw(self) -> NonNull<PyObject> {
let ptr = self.ptr;
std::mem::forget(self);
ptr
}
@@ -518,10 +520,8 @@ impl PyObjectRef {
/// dropped more than once due to mishandling the reference count by calling this function
/// too many times.
#[inline(always)]
pub unsafe fn from_raw(ptr: *const PyObject) -> Self {
Self {
ptr: NonNull::new_unchecked(ptr as *mut PyObject),
}
pub unsafe fn from_raw(ptr: NonNull<PyObject>) -> Self {
Self { ptr }
}
/// Attempt to downcast this reference to a subclass.
@@ -567,7 +567,8 @@ impl PyObjectRef {
#[inline(always)]
pub unsafe fn downcast_unchecked_ref<T: PyObjectPayload>(&self) -> &Py<T> {
debug_assert!(self.payload_is::<T>());
&*(self as *const PyObjectRef as *const PyRef<T>)
// SAFETY: requirements forwarded from caller
unsafe { &*(self as *const PyObjectRef as *const PyRef<T>) }
}
// ideally we'd be able to define these in pyobject.rs, but method visibility rules are weird
@@ -752,7 +753,8 @@ impl PyObject {
#[inline(always)]
pub unsafe fn downcast_unchecked_ref<T: PyObjectPayload>(&self) -> &Py<T> {
debug_assert!(self.payload_is::<T>());
&*(self as *const PyObject as *const Py<T>)
// SAFETY: requirements forwarded from caller
unsafe { &*(self as *const PyObject as *const Py<T>) }
}
#[inline(always)]
@@ -814,13 +816,13 @@ impl PyObject {
/// Can only be called when ref_count has dropped to zero. `ptr` must be valid
#[inline(never)]
unsafe fn drop_slow(ptr: NonNull<PyObject>) {
if let Err(()) = ptr.as_ref().drop_slow_inner() {
if let Err(()) = unsafe { ptr.as_ref().drop_slow_inner() } {
// abort drop for whatever reason
return;
}
let drop_dealloc = ptr.as_ref().0.vtable.drop_dealloc;
let drop_dealloc = unsafe { ptr.as_ref().0.vtable.drop_dealloc };
// call drop only when there are no references in scope - stacked borrows stuff
drop_dealloc(ptr.as_ptr())
unsafe { drop_dealloc(ptr.as_ptr()) }
}
/// # Safety
@@ -1022,7 +1024,7 @@ impl<T: PyObjectPayload> PyRef<T> {
#[inline(always)]
pub(crate) unsafe fn from_raw(raw: *const Py<T>) -> Self {
Self {
ptr: NonNull::new_unchecked(raw as *mut _),
ptr: unsafe { NonNull::new_unchecked(raw as *mut _) },
}
}

View File

@@ -12,7 +12,13 @@ use crate::{
vm::Context,
VirtualMachine,
};
use std::{borrow::Borrow, fmt, marker::PhantomData, ops::Deref, ptr::null_mut};
use std::{
borrow::Borrow,
fmt,
marker::PhantomData,
ops::Deref,
ptr::{null_mut, NonNull},
};
/* Python objects and references.
@@ -60,7 +66,7 @@ impl<T: PyPayload> PyExact<T> {
/// Given reference must be exact type of payload T
#[inline(always)]
pub unsafe fn ref_unchecked(r: &Py<T>) -> &Self {
&*(r as *const _ as *const Self)
unsafe { &*(r as *const _ as *const Self) }
}
}
@@ -294,7 +300,7 @@ impl<T: PyObjectPayload> PyAtomicRef<T> {
pub unsafe fn swap(&self, pyref: PyRef<T>) -> PyRef<T> {
let py = PyRef::leak(pyref) as *const Py<T> as *mut _;
let old = Radium::swap(&self.inner, py, Ordering::AcqRel);
PyRef::from_raw(old.cast())
unsafe { PyRef::from_raw(old.cast()) }
}
pub fn swap_to_temporary_refs(&self, pyref: PyRef<T>, vm: &VirtualMachine) {
@@ -352,7 +358,7 @@ impl From<PyObjectRef> for PyAtomicRef<PyObject> {
fn from(obj: PyObjectRef) -> Self {
let obj = obj.into_raw();
Self {
inner: Radium::new(obj as *mut _),
inner: Radium::new(obj.cast().as_ptr()),
_phantom: Default::default(),
}
}
@@ -379,8 +385,8 @@ impl PyAtomicRef<PyObject> {
#[must_use]
pub unsafe fn swap(&self, obj: PyObjectRef) -> PyObjectRef {
let obj = obj.into_raw();
let old = Radium::swap(&self.inner, obj as *mut _, Ordering::AcqRel);
PyObjectRef::from_raw(old as _)
let old = Radium::swap(&self.inner, obj.cast().as_ptr(), Ordering::AcqRel);
unsafe { PyObjectRef::from_raw(NonNull::new_unchecked(old.cast())) }
}
pub fn swap_to_temporary_refs(&self, obj: PyObjectRef, vm: &VirtualMachine) {
@@ -393,7 +399,9 @@ impl PyAtomicRef<PyObject> {
impl From<Option<PyObjectRef>> for PyAtomicRef<Option<PyObject>> {
fn from(obj: Option<PyObjectRef>) -> Self {
let val = obj.map(|x| x.into_raw() as *mut _).unwrap_or(null_mut());
let val = obj
.map(|x| x.into_raw().as_ptr().cast())
.unwrap_or(null_mut());
Self {
inner: Radium::new(val),
_phantom: Default::default(),
@@ -420,11 +428,11 @@ impl PyAtomicRef<Option<PyObject>> {
/// until no more reference can be used via PyAtomicRef::deref()
#[must_use]
pub unsafe fn swap(&self, obj: Option<PyObjectRef>) -> Option<PyObjectRef> {
let val = obj.map(|x| x.into_raw() as *mut _).unwrap_or(null_mut());
let val = obj
.map(|x| x.into_raw().as_ptr().cast())
.unwrap_or(null_mut());
let old = Radium::swap(&self.inner, val, Ordering::AcqRel);
old.cast::<PyObject>()
.as_ref()
.map(|x| PyObjectRef::from_raw(x))
unsafe { NonNull::new(old.cast::<PyObject>()).map(|x| PyObjectRef::from_raw(x)) }
}
pub fn swap_to_temporary_refs(&self, obj: Option<PyObjectRef>, vm: &VirtualMachine) {

View File

@@ -133,8 +133,11 @@ impl PyBuffer {
// after this function, the owner should use forget()
// or wrap PyBuffer in the ManaullyDrop to prevent drop()
pub(crate) unsafe fn drop_without_release(&mut self) {
std::ptr::drop_in_place(&mut self.obj);
std::ptr::drop_in_place(&mut self.desc);
// SAFETY: requirements forwarded from caller
unsafe {
std::ptr::drop_in_place(&mut self.obj);
std::ptr::drop_in_place(&mut self.desc);
}
}
}

View File

@@ -24,7 +24,7 @@ mod msvcrt {
unsafe { suppress_iph!(_setmode(fd, libc::O_BINARY)) };
}
extern "C" {
unsafe extern "C" {
fn _getch() -> i32;
fn _getwch() -> u32;
fn _getche() -> i32;
@@ -70,7 +70,7 @@ mod msvcrt {
Ok(())
}
extern "C" {
unsafe extern "C" {
fn _setmode(fd: i32, flags: i32) -> i32;
}
@@ -84,7 +84,7 @@ mod msvcrt {
}
}
extern "C" {
unsafe extern "C" {
fn _open_osfhandle(osfhandle: isize, flags: i32) -> i32;
fn _get_osfhandle(fd: i32) -> libc::intptr_t;
}

View File

@@ -116,7 +116,7 @@ pub(crate) mod module {
// cwait is available on MSVC only (according to CPython)
#[cfg(target_env = "msvc")]
extern "C" {
unsafe extern "C" {
fn _cwait(termstat: *mut i32, procHandle: intptr_t, action: i32) -> intptr_t;
}
@@ -194,7 +194,7 @@ pub(crate) mod module {
}
#[cfg(target_env = "msvc")]
extern "C" {
unsafe extern "C" {
fn _wexecv(cmdname: *const u16, argv: *const *const u16) -> intptr_t;
}

View File

@@ -966,7 +966,7 @@ pub(super) mod _os {
#[pyfunction]
fn abort() {
extern "C" {
unsafe extern "C" {
fn abort();
}
unsafe { abort() }

View File

@@ -971,7 +971,7 @@ pub mod module {
#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "netbsd",))]
#[pyfunction]
fn lchmod(path: OsPath, mode: u32, vm: &VirtualMachine) -> PyResult<()> {
extern "C" {
unsafe extern "C" {
fn lchmod(path: *const libc::c_char, mode: libc::mode_t) -> libc::c_int;
}
let c_path = path.clone().into_cstring(vm)?;
@@ -1605,7 +1605,7 @@ pub mod module {
// from libstd:
// https://github.com/rust-lang/rust/blob/daecab3a784f28082df90cebb204998051f3557d/src/libstd/sys/unix/fs.rs#L1251
#[cfg(target_os = "macos")]
extern "C" {
unsafe extern "C" {
fn fcopyfile(
in_fd: libc::c_int,
out_fd: libc::c_int,
@@ -2299,7 +2299,7 @@ pub mod module {
#[cfg(target_os = "linux")]
unsafe fn sys_getrandom(buf: *mut libc::c_void, buflen: usize, flags: u32) -> isize {
libc::syscall(libc::SYS_getrandom, buf, buflen, flags as usize) as _
unsafe { libc::syscall(libc::SYS_getrandom, buf, buflen, flags as usize) as _ }
}
#[cfg(target_os = "linux")]

View File

@@ -78,7 +78,7 @@ pub(crate) mod _signal {
pub const SIG_ERR: sighandler_t = -1 as _;
#[cfg(all(unix, not(target_os = "redox")))]
extern "C" {
unsafe extern "C" {
fn siginterrupt(sig: i32, flag: i32) -> i32;
}

View File

@@ -17,7 +17,7 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyRef<PyModule> {
#[cfg(not(target_env = "msvc"))]
#[cfg(not(target_arch = "wasm32"))]
extern "C" {
unsafe extern "C" {
#[cfg(not(target_os = "freebsd"))]
#[link_name = "daylight"]
static c_daylight: std::ffi::c_int;
@@ -209,7 +209,9 @@ mod decl {
use crate::builtins::tuple::IntoPyTuple;
unsafe fn to_str(s: *const std::ffi::c_char) -> String {
std::ffi::CStr::from_ptr(s).to_string_lossy().into_owned()
unsafe { std::ffi::CStr::from_ptr(s) }
.to_string_lossy()
.into_owned()
}
unsafe { (to_str(super::c_tzname[0]), to_str(super::c_tzname[1])) }.into_pytuple(vm)
}

View File

@@ -62,7 +62,7 @@ macro_rules! declare_const_name {
impl ConstName {
unsafe fn new(pool: &StringPool, typ: &PyTypeRef) -> Self {
Self {
$($name: pool.intern(stringify!($name), typ.clone()),)*
$($name: unsafe { pool.intern(stringify!($name), typ.clone()) },)*
}
}
}