diff --git a/crates/stdlib/src/lib.rs b/crates/stdlib/src/lib.rs index 6d9150022..4670b07f0 100644 --- a/crates/stdlib/src/lib.rs +++ b/crates/stdlib/src/lib.rs @@ -5,6 +5,7 @@ #[macro_use] extern crate rustpython_derive; + extern crate alloc; #[macro_use] @@ -20,8 +21,10 @@ mod cmath; mod compression; // internal module mod contextvars; mod csv; + #[cfg(not(any(target_os = "android", target_arch = "wasm32")))] mod lzma; + mod zlib; mod blake2; @@ -41,30 +44,40 @@ mod json; mod locale; mod _opcode; + #[path = "_tokenize.rs"] mod _tokenize; + mod math; + #[cfg(all(feature = "host_env", any(unix, windows)))] mod mmap; + mod pyexpat; mod pystruct; mod random; mod statistics; mod suggestions; + // TODO: maybe make this an extension module, if we ever get those // mod re; #[cfg(all(feature = "host_env", not(target_arch = "wasm32")))] pub mod socket; + #[cfg(all(feature = "host_env", unix, not(target_os = "redox")))] mod syslog; + mod unicodedata; #[cfg(feature = "host_env")] mod faulthandler; + #[cfg(all(feature = "host_env", any(unix, target_os = "wasi")))] mod fcntl; + #[cfg(all(feature = "host_env", not(target_arch = "wasm32")))] mod multiprocessing; + #[cfg(all( feature = "host_env", unix, @@ -72,28 +85,36 @@ mod multiprocessing; not(target_os = "android") ))] mod posixshmem; + #[cfg(all(feature = "host_env", unix))] mod posixsubprocess; + // libc is missing constants on redox #[cfg(all( feature = "sqlite", not(any(target_os = "android", target_arch = "wasm32")) ))] mod _sqlite3; + #[cfg(all(feature = "host_env", windows))] mod _testconsole; + #[cfg(all( feature = "host_env", unix, not(any(target_os = "android", target_os = "redox")) ))] mod grp; + #[cfg(all(feature = "host_env", windows))] mod overlapped; + #[cfg(all(feature = "host_env", unix, not(target_os = "redox")))] mod resource; + #[cfg(all(feature = "host_env", target_os = "macos"))] mod scproxy; + #[cfg(all(feature = "host_env", any(unix, windows, target_os = "wasi")))] mod select; @@ -103,14 +124,16 @@ mod select; feature = "ssl-openssl" ))] mod openssl; + #[cfg(all( feature = "host_env", not(target_arch = "wasm32"), feature = "ssl-rustls" ))] mod ssl; -#[cfg(all(feature = "ssl-openssl", feature = "ssl-rustls"))] -compile_error!("features \"ssl-openssl\" and \"ssl-rustls\" are mutually exclusive"); + +#[cfg(all(feature = "ssl-openssl", feature = "ssl-rustls", not(clippy)))] +compile_error!(r#"features "ssl-openssl" and "ssl-rustls" are mutually exclusive"#); #[cfg(all( feature = "host_env", @@ -119,6 +142,7 @@ compile_error!("features \"ssl-openssl\" and \"ssl-rustls\" are mutually exclusi not(target_os = "ios") ))] mod termios; + #[cfg(all( feature = "host_env", not(any( diff --git a/crates/stdlib/src/openssl.rs b/crates/stdlib/src/openssl.rs index 066f85167..24cbe8a40 100644 --- a/crates/stdlib/src/openssl.rs +++ b/crates/stdlib/src/openssl.rs @@ -3,6 +3,10 @@ mod cert; // SSL exception types (shared with rustls backend) +#[allow( + clippy::duplicate_mod, + reason = "This is duplicated only when running clippy. The two features are mutually exclusive" +)] #[path = "ssl/error.rs"] mod ssl_error; @@ -33,7 +37,7 @@ use rustpython_common::lock::LazyLock; // define our own copy of ProbeResult so we can handle the vendor case // easily, without having to have a bunch of cfgs static PROBE: LazyLock = cfg_select! { - openssl_vendored => LazyLock::new(openssl_probe::probe) + openssl_vendored => LazyLock::new(openssl_probe::probe), _ => LazyLock::new(|| ProbeResult { cert_file: None, cert_dir: vec![] }) }; @@ -90,9 +94,9 @@ mod _ssl { }; use openssl_sys as sys; use rustpython_vm::ospath::OsPath; + + use core::{ffi::CStr, fmt}; use std::{ - ffi::CStr, - fmt, io::{Read, Write}, path::{Path, PathBuf}, time::Instant, @@ -574,7 +578,7 @@ mod _ssl { static SNI_EX_DATA_IDX: LazyLock = LazyLock::new(|| unsafe { sys::SSL_get_ex_new_index( 0, - std::ptr::null_mut(), + core::ptr::null_mut(), None, None, Some(sni_callback_data_free), @@ -607,7 +611,7 @@ mod _ssl { // Free the Box - this releases references to context and socket let _ = Box::from_raw(data_ptr as *mut SniCallbackData); // Clear the ex_data to prevent double-free - sys::SSL_set_ex_data(ssl_ptr, idx, std::ptr::null_mut()); + sys::SSL_set_ex_data(ssl_ptr, idx, core::ptr::null_mut()); } } } @@ -618,7 +622,7 @@ mod _ssl { static MSG_CB_EX_DATA_IDX: LazyLock = LazyLock::new(|| unsafe { sys::SSL_get_ex_new_index( 0, - std::ptr::null_mut(), + core::ptr::null_mut(), None, None, Some(msg_callback_data_free), @@ -639,7 +643,7 @@ mod _ssl { if !ptr.is_null() { unsafe { // Reconstruct PyObjectRef and drop to decrement reference count - let raw = std::ptr::NonNull::new_unchecked(ptr as *mut PyObject); + let raw = core::ptr::NonNull::new_unchecked(ptr as *mut PyObject); let _ = PyObjectRef::from_raw(raw); } } @@ -691,7 +695,7 @@ mod _ssl { let server_name_arg = if servername.is_null() { vm.ctx.none() } else { - let name_cstr = std::ffi::CStr::from_ptr(servername); + let name_cstr = core::ffi::CStr::from_ptr(servername); match name_cstr.to_str() { Ok(name_str) => vm.ctx.new_str(name_str).into(), Err(_) => vm.ctx.none(), @@ -807,7 +811,7 @@ mod _ssl { .unwrap_or_else(|| vm.ctx.none()); // Create the message bytes - let buf_slice = std::slice::from_raw_parts(buf as *const u8, len); + let buf_slice = core::slice::from_raw_parts(buf as *const u8, len); let msg_bytes = vm.ctx.new_bytes(buf_slice.to_vec()); // Determine direction string @@ -816,34 +820,22 @@ mod _ssl { // Calculate msg_type based on content_type (debughelpers.c behavior) let msg_type = match content_type { SSL3_RT_CHANGE_CIPHER_SPEC => SSL3_MT_CHANGE_CIPHER_SPEC, - SSL3_RT_ALERT => { + SSL3_RT_ALERT if len >= 2 => { // byte 1 is alert type - if len >= 2 { buf_slice[1] as i32 } else { -1 } + buf_slice[1] as i32 } - SSL3_RT_HANDSHAKE => { + SSL3_RT_HANDSHAKE if !buf_slice.is_empty() => { // byte 0 is handshake type - if !buf_slice.is_empty() { - buf_slice[0] as i32 - } else { - -1 - } + buf_slice[0] as i32 } - SSL3_RT_HEADER => { + SSL3_RT_HEADER if len >= 3 => { // Frame header: version in bytes 1..2, type in byte 0 - if len >= 3 { - version = ((buf_slice[1] as i32) << 8) | (buf_slice[2] as i32); - buf_slice[0] as i32 - } else { - -1 - } + version = ((buf_slice[1] as i32) << 8) | (buf_slice[2] as i32); + buf_slice[0] as i32 } - SSL3_RT_INNER_CONTENT_TYPE => { + SSL3_RT_INNER_CONTENT_TYPE if !buf_slice.is_empty() => { // Inner content type in byte 0 - if !buf_slice.is_empty() { - buf_slice[0] as i32 - } else { - -1 - } + buf_slice[0] as i32 } _ => -1, }; @@ -1686,9 +1678,9 @@ mod _ssl { let dh = unsafe { PEM_read_DHparams( fp, - std::ptr::null_mut(), - std::ptr::null_mut(), - std::ptr::null_mut(), + core::ptr::null_mut(), + core::ptr::null_mut(), + core::ptr::null_mut(), ) }; unsafe { @@ -1832,8 +1824,8 @@ mod _ssl { #[pymethod] fn load_cert_chain(&self, args: LoadCertChainArgs, vm: &VirtualMachine) -> PyResult<()> { + use core::cell::RefCell; use openssl::pkey::PKey; - use std::cell::RefCell; let LoadCertChainArgs { certfile, @@ -2043,7 +2035,7 @@ mod _ssl { if hostname_str.contains('\0') { return Err(vm.new_type_error("embedded null character")); } - let ip = hostname_str.parse::(); + let ip = hostname_str.parse::(); if ip.is_err() { ssl.set_hostname(hostname_str) .map_err(|e| convert_openssl_error(vm, e))?; @@ -2734,7 +2726,7 @@ mod _ssl { if out.is_null() { None } else { - let slice = std::slice::from_raw_parts(out, outlen as usize); + let slice = core::slice::from_raw_parts(out, outlen as usize); Some(String::from_utf8_lossy(slice).into_owned()) } } @@ -3114,7 +3106,7 @@ mod _ssl { .ok_or_else(|| vm.new_type_error("Value is not a SSLSession."))?; // Check if session refers to the same SSLContext - if !std::ptr::eq( + if !core::ptr::eq( self.ctx.read().ctx.read().as_ptr(), session.ctx.ctx.read().as_ptr(), ) { @@ -3319,8 +3311,8 @@ mod _ssl { if self_len != other_len { false } else { - let self_slice = std::slice::from_raw_parts(self_id, self_len as usize); - let other_slice = std::slice::from_raw_parts(other_id, other_len as usize); + let self_slice = core::slice::from_raw_parts(self_id, self_len as usize); + let other_slice = core::slice::from_raw_parts(other_id, other_len as usize); self_slice == other_slice } }; @@ -3443,7 +3435,14 @@ mod _ssl { // SSL session statistics functions (implemented as macros in OpenSSL) #[allow(non_snake_case)] unsafe fn SSL_CTX_sess_number(ctx: *const sys::SSL_CTX) -> libc::c_long { - unsafe { sys::SSL_CTX_ctrl(ctx as *mut _, SSL_CTRL_SESS_NUMBER, 0, std::ptr::null_mut()) } + unsafe { + sys::SSL_CTX_ctrl( + ctx as *mut _, + SSL_CTRL_SESS_NUMBER, + 0, + core::ptr::null_mut(), + ) + } } #[allow(non_snake_case)] @@ -3453,7 +3452,7 @@ mod _ssl { ctx as *mut _, SSL_CTRL_SESS_CONNECT, 0, - std::ptr::null_mut(), + core::ptr::null_mut(), ) } } @@ -3465,7 +3464,7 @@ mod _ssl { ctx as *mut _, SSL_CTRL_SESS_CONNECT_GOOD, 0, - std::ptr::null_mut(), + core::ptr::null_mut(), ) } } @@ -3477,14 +3476,21 @@ mod _ssl { ctx as *mut _, SSL_CTRL_SESS_CONNECT_RENEGOTIATE, 0, - std::ptr::null_mut(), + core::ptr::null_mut(), ) } } #[allow(non_snake_case)] unsafe fn SSL_CTX_sess_accept(ctx: *const sys::SSL_CTX) -> libc::c_long { - unsafe { sys::SSL_CTX_ctrl(ctx as *mut _, SSL_CTRL_SESS_ACCEPT, 0, std::ptr::null_mut()) } + unsafe { + sys::SSL_CTX_ctrl( + ctx as *mut _, + SSL_CTRL_SESS_ACCEPT, + 0, + core::ptr::null_mut(), + ) + } } #[allow(non_snake_case)] @@ -3494,7 +3500,7 @@ mod _ssl { ctx as *mut _, SSL_CTRL_SESS_ACCEPT_GOOD, 0, - std::ptr::null_mut(), + core::ptr::null_mut(), ) } } @@ -3506,19 +3512,26 @@ mod _ssl { ctx as *mut _, SSL_CTRL_SESS_ACCEPT_RENEGOTIATE, 0, - std::ptr::null_mut(), + core::ptr::null_mut(), ) } } #[allow(non_snake_case)] unsafe fn SSL_CTX_sess_hits(ctx: *const sys::SSL_CTX) -> libc::c_long { - unsafe { sys::SSL_CTX_ctrl(ctx as *mut _, SSL_CTRL_SESS_HIT, 0, std::ptr::null_mut()) } + unsafe { sys::SSL_CTX_ctrl(ctx as *mut _, SSL_CTRL_SESS_HIT, 0, core::ptr::null_mut()) } } #[allow(non_snake_case)] unsafe fn SSL_CTX_sess_misses(ctx: *const sys::SSL_CTX) -> libc::c_long { - unsafe { sys::SSL_CTX_ctrl(ctx as *mut _, SSL_CTRL_SESS_MISSES, 0, std::ptr::null_mut()) } + unsafe { + sys::SSL_CTX_ctrl( + ctx as *mut _, + SSL_CTRL_SESS_MISSES, + 0, + core::ptr::null_mut(), + ) + } } #[allow(non_snake_case)] @@ -3528,7 +3541,7 @@ mod _ssl { ctx as *mut _, SSL_CTRL_SESS_TIMEOUTS, 0, - std::ptr::null_mut(), + core::ptr::null_mut(), ) } } @@ -3540,7 +3553,7 @@ mod _ssl { ctx as *mut _, SSL_CTRL_SESS_CACHE_FULL, 0, - std::ptr::null_mut(), + core::ptr::null_mut(), ) } } @@ -3562,7 +3575,7 @@ mod _ssl { #[allow(non_snake_case)] unsafe fn BIO_ctrl_pending(bio: *mut sys::BIO) -> usize { - unsafe { sys::BIO_ctrl(bio, BIO_CTRL_PENDING, 0, std::ptr::null_mut()) as usize } + unsafe { sys::BIO_ctrl(bio, BIO_CTRL_PENDING, 0, core::ptr::null_mut()) as usize } } #[allow(non_snake_case)] @@ -3572,7 +3585,7 @@ mod _ssl { bio, BIO_CTRL_SET_EOF, eof as libc::c_long, - std::ptr::null_mut(), + core::ptr::null_mut(), ) as libc::c_int } } @@ -3705,7 +3718,7 @@ mod _ssl { unsafe { let mut len: libc::c_uint = 0; let id_ptr = sys::SSL_SESSION_get_id(self.session, &mut len); - let id_slice = std::slice::from_raw_parts(id_ptr, len as usize); + let id_slice = core::slice::from_raw_parts(id_ptr, len as usize); vm.ctx.new_bytes(id_slice.to_vec()) } } @@ -3849,7 +3862,7 @@ mod _ssl { if verify_str.is_null() { vm.ctx.none() } else { - let c_str = std::ffi::CStr::from_ptr(verify_str); + let c_str = core::ffi::CStr::from_ptr(verify_str); vm.ctx.new_str(c_str.to_string_lossy()).into() } }; @@ -3919,12 +3932,12 @@ mod _ssl { loop { // Check for EOF before attempting to parse (like CPython's _add_ca_certs) // BIO_ctrl with BIO_CTRL_EOF returns 1 if EOF, 0 otherwise - if sys::BIO_ctrl(bio.as_ptr(), sys::BIO_CTRL_EOF, 0, std::ptr::null_mut()) != 0 { + if sys::BIO_ctrl(bio.as_ptr(), sys::BIO_CTRL_EOF, 0, core::ptr::null_mut()) != 0 { was_bio_eof = true; break; } - let cert = sys::d2i_X509_bio(bio.as_ptr(), std::ptr::null_mut()); + let cert = sys::d2i_X509_bio(bio.as_ptr(), core::ptr::null_mut()); if cert.is_null() { // Parse error (not just EOF) break; diff --git a/crates/stdlib/src/openssl/cert.rs b/crates/stdlib/src/openssl/cert.rs index 4f0e222f1..e18e7feb9 100644 --- a/crates/stdlib/src/openssl/cert.rs +++ b/crates/stdlib/src/openssl/cert.rs @@ -21,7 +21,8 @@ pub(crate) mod ssl_cert { x509::{self, X509, X509Ref}, }; use openssl_sys as sys; - use std::fmt; + + use core::fmt; // Import constants and error converter from _ssl module use crate::openssl::_ssl::{ENCODING_DER, ENCODING_PEM, convert_openssl_error}; @@ -30,7 +31,7 @@ pub(crate) mod ssl_cert { let no_name = i32::from(no_name); let ptr = obj.as_ptr(); let b = unsafe { - let buflen = sys::OBJ_obj2txt(std::ptr::null_mut(), 0, ptr, no_name); + let buflen = sys::OBJ_obj2txt(core::ptr::null_mut(), 0, ptr, no_name); assert!(buflen >= 0); if buflen == 0 { return None; @@ -172,7 +173,7 @@ pub(crate) mod ssl_cert { let txt = obj2txt(entry.object(), false).to_pyobject(vm); let asn1_str = entry.data(); let data_bytes = asn1_str.as_slice(); - let data = match std::str::from_utf8(data_bytes) { + let data = match core::str::from_utf8(data_bytes) { Ok(s) => vm.ctx.new_str(s.to_owned()), Err(_) => vm .ctx @@ -234,8 +235,9 @@ pub(crate) mod ssl_cert { format!("{}.{}.{}.{}", ip[0], ip[1], ip[2], ip[3]) } else if ip.len() == 16 { // IPv6 - format with all zeros visible (not compressed) - let ip_addr = - std::net::Ipv6Addr::from(<[u8; 16]>::try_from(&ip[0..16]).unwrap()); + let ip_addr = core::net::Ipv6Addr::from( + <[u8; 16]>::try_from(&ip[0..16]).unwrap(), + ); let s = ip_addr.segments(); format!( "{:X}:{:X}:{:X}:{:X}:{:X}:{:X}:{:X}:{:X}", diff --git a/crates/stdlib/src/ssl/compat.rs b/crates/stdlib/src/ssl/compat.rs index 29e3687e9..079e7f762 100644 --- a/crates/stdlib/src/ssl/compat.rs +++ b/crates/stdlib/src/ssl/compat.rs @@ -8,6 +8,10 @@ // SSL error code data tables (shared with OpenSSL backend for compatibility) // These map OpenSSL error codes to human-readable strings +#[allow( + clippy::duplicate_mod, + reason = "This is duplicated only when running clippy. The two features are mutually exclusive" +)] #[path = "../openssl/ssl_data_31.rs"] mod ssl_data; diff --git a/crates/stdlib/src/ssl/error.rs b/crates/stdlib/src/ssl/error.rs index 07ff44886..d12cd834d 100644 --- a/crates/stdlib/src/ssl/error.rs +++ b/crates/stdlib/src/ssl/error.rs @@ -125,6 +125,7 @@ pub(crate) mod ssl_error { ) } + #[allow(dead_code, reason = "This seems like a false positive")] pub(crate) fn create_ssl_zero_return_error(vm: &VirtualMachine) -> PyRef { vm.new_os_subtype_error( PySSLZeroReturnError::class(&vm.ctx).to_owned(), @@ -133,6 +134,7 @@ pub(crate) mod ssl_error { ) } + #[allow(dead_code, reason = "This seems like a false positive")] pub(crate) fn create_ssl_syscall_error( vm: &VirtualMachine, msg: impl Into, diff --git a/crates/stdlib/src/tkinter.rs b/crates/stdlib/src/tkinter.rs index b19468a7f..0ccc0a97f 100644 --- a/crates/stdlib/src/tkinter.rs +++ b/crates/stdlib/src/tkinter.rs @@ -80,6 +80,7 @@ mod _tkinter { static QUIT_MAIN_LOOP: AtomicBool = AtomicBool::new(false); static ERROR_IN_CMD: AtomicBool = AtomicBool::new(false); + #[expect(dead_code, reason = "TODO: Impl more methods")] #[pyattr] #[pyclass(name = "tkapp")] #[derive(PyPayload)] @@ -154,8 +155,9 @@ mod _tkinter { // } // str - if let Some(str) = obj.downcast_ref::() { - return Ok(str.as_str().to_string()); + + if let Some(varname) = obj.downcast_ref::().map(|s| s.to_string()) { + return Ok(varname); } if let Some(_tcl_obj) = obj.downcast_ref::() { @@ -167,7 +169,7 @@ mod _tkinter { // Construct an error message using the type name (truncated to 50 characters). Err(vm.new_type_error(format!( "must be str, bytes or Tcl_Obj, not {:.50}", - obj.obj_type().str(vm)?.as_str() + obj.class().name(), ))) } diff --git a/crates/vm/src/builtins/function/jit.rs b/crates/vm/src/builtins/function/jit.rs index 56594a0f4..8432bb536 100644 --- a/crates/vm/src/builtins/function/jit.rs +++ b/crates/vm/src/builtins/function/jit.rs @@ -11,7 +11,7 @@ use num_traits::ToPrimitive; use rustpython_jit::{AbiValue, Args, CompiledCode, JitArgumentError, JitType}; #[derive(Debug, thiserror::Error)] -pub enum ArgsError { +pub(super) enum ArgsError { #[error("wrong number of arguments passed")] WrongNumberOfArgs, #[error("argument passed multiple times")] @@ -39,7 +39,7 @@ impl ToPyObject for AbiValue { } } -pub fn new_jit_error(msg: String, vm: &VirtualMachine) -> PyBaseExceptionRef { +pub(super) fn new_jit_error(msg: String, vm: &VirtualMachine) -> PyBaseExceptionRef { let jit_error = vm.ctx.exceptions.jit_error.to_owned(); vm.new_exception_msg(jit_error, msg.into()) } @@ -66,7 +66,10 @@ fn get_jit_arg_type(dict: &Py, name: &str, vm: &VirtualMachine) -> PyRes } } -pub fn get_jit_arg_types(func: &Py, vm: &VirtualMachine) -> PyResult> { +pub(super) fn get_jit_arg_types( + func: &Py, + vm: &VirtualMachine, +) -> PyResult> { let code: &Py = &func.code; let arg_names = code.arg_names(); @@ -108,7 +111,10 @@ pub fn get_jit_arg_types(func: &Py, vm: &VirtualMachine) -> PyResult } } -pub fn jit_ret_type(func: &Py, vm: &VirtualMachine) -> PyResult> { +pub(super) fn jit_ret_type( + func: &Py, + vm: &VirtualMachine, +) -> PyResult> { let func_obj: PyObjectRef = func.as_ref().to_owned(); let annotations = func_obj.get_attr("__annotations__", vm)?; if vm.is_none(&annotations) { diff --git a/crates/vm/src/frame.rs b/crates/vm/src/frame.rs index f20f85529..f95946e03 100644 --- a/crates/vm/src/frame.rs +++ b/crates/vm/src/frame.rs @@ -1,8 +1,7 @@ // spell-checker: ignore compactlong compactlongs use crate::anystr::AnyStr; -#[cfg(feature = "flame")] -use crate::bytecode::InstructionMetadata; + use crate::{ AsObject, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyResult, PyStackRef, TryFromObject, VirtualMachine, @@ -2096,8 +2095,7 @@ impl ExecutingFrame<'_> { vm: &VirtualMachine, ) -> FrameResult { flame_guard!(format!( - "Frame::execute_instruction({})", - instruction.display(arg, &self.code.code).to_string() + "Frame::execute_instruction({instruction:?} {arg:?})" )); #[cfg(feature = "vm-tracing-logging")] @@ -2109,10 +2107,7 @@ impl ExecutingFrame<'_> { } */ trace!(" {:#?}", self); - trace!( - " Executing op code: {}", - instruction.display(arg, &self.code.code) - ); + trace!(" Executing opcode: {instruction:?} {arg:?}",); trace!("======="); } diff --git a/crates/vm/src/stdlib/_io.rs b/crates/vm/src/stdlib/_io.rs index a910e5e6c..3eb4985e1 100644 --- a/crates/vm/src/stdlib/_io.rs +++ b/crates/vm/src/stdlib/_io.rs @@ -2,6 +2,7 @@ * I/O core tools. */ pub(crate) use _io::module_def; + #[cfg(all(unix, feature = "threading", feature = "host_env"))] pub(crate) use _io::reinit_std_streams_after_fork; diff --git a/crates/vm/src/stdlib/_thread.rs b/crates/vm/src/stdlib/_thread.rs index e1708cb05..3ce360996 100644 --- a/crates/vm/src/stdlib/_thread.rs +++ b/crates/vm/src/stdlib/_thread.rs @@ -1,7 +1,10 @@ //! Implementation of the _thread module + #[cfg(all(unix, feature = "threading", feature = "host_env"))] pub(crate) use _thread::after_fork_child; + pub use _thread::get_ident; + #[cfg_attr(target_arch = "wasm32", allow(unused_imports))] pub(crate) use _thread::{ CurrentFrameSlot, HandleEntry, RawRMutex, ShutdownEntry, get_all_current_frames, @@ -463,6 +466,7 @@ pub(crate) mod _thread { use std::os::unix::thread::JoinHandleExt; handle.as_pthread_t() as _ } + #[cfg(not(unix))] { thread_to_rust_id(handle.thread())