From 2f76ef654b8ca5a67b9a756bde4a843159a5afbf Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:27:29 +0200 Subject: [PATCH 1/3] Add workspace lint --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index 7471a3becc4..c326b41d62c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -222,6 +222,7 @@ wasm-bindgen = "0.2.106" unsafe_code = "allow" unsafe_op_in_unsafe_fn = "deny" elided_lifetimes_in_paths = "warn" +missing_copy_implementations = "warn" [workspace.lints.clippy] # alloc_instead_of_core = "warn" From a9364cbc524aaa9591fe218726cae8b45cb6bebe Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:27:44 +0200 Subject: [PATCH 2/3] Fix warnings --- crates/codegen/src/compile.rs | 3 ++- crates/codegen/src/error.rs | 2 +- crates/codegen/src/ir.rs | 6 +++--- crates/codegen/src/symboltable.rs | 2 +- crates/common/src/cformat.rs | 4 ++-- crates/common/src/encodings.rs | 7 +++++++ crates/common/src/fileutils.rs | 6 ++++-- crates/common/src/format.rs | 10 +++++----- crates/common/src/hash.rs | 1 + crates/common/src/int.rs | 2 +- crates/common/src/lock/cell_lock.rs | 6 +++++- crates/common/src/lock/thread_mutex.rs | 8 ++++++-- crates/common/src/str.rs | 1 + crates/compiler-core/src/bytecode.rs | 4 ++-- crates/compiler-core/src/marshal.rs | 3 ++- crates/compiler-core/src/mode.rs | 2 +- crates/sre_engine/src/constants.rs | 14 ++++++++------ crates/vm/src/anystr.rs | 4 ++-- crates/vm/src/builtins/descriptor.rs | 4 +++- crates/vm/src/builtins/module.rs | 6 +++--- crates/vm/src/builtins/namespace.rs | 4 ++-- crates/vm/src/builtins/object.rs | 2 +- crates/vm/src/builtins/singletons.rs | 4 ++-- crates/vm/src/builtins/slice.rs | 2 +- crates/vm/src/builtins/zip.rs | 2 +- crates/vm/src/dict_inner.rs | 2 +- crates/vm/src/function/method.rs | 4 ++-- crates/vm/src/function/number.rs | 6 +++--- crates/vm/src/protocol/buffer.rs | 1 + crates/vm/src/protocol/mapping.rs | 2 +- crates/vm/src/protocol/sequence.rs | 2 +- crates/vm/src/sliceable.rs | 2 ++ crates/vm/src/stdlib/marshal.rs | 1 + crates/vm/src/stdlib/os.rs | 2 +- crates/vm/src/stdlib/typevar.rs | 4 ++-- crates/vm/src/stdlib/typing.rs | 2 +- crates/wasm/src/vm_class.rs | 1 + 37 files changed, 84 insertions(+), 54 deletions(-) diff --git a/crates/codegen/src/compile.rs b/crates/codegen/src/compile.rs index 2f28c6c9683..061f356fe94 100644 --- a/crates/codegen/src/compile.rs +++ b/crates/codegen/src/compile.rs @@ -113,13 +113,14 @@ struct Compiler { in_annotation: bool, } +#[derive(Clone, Copy)] enum DoneWithFuture { No, DoneWithDoc, Yes, } -#[derive(Debug, Clone)] +#[derive(Clone, Copy, Debug)] pub struct CompileOpts { /// How optimized the bytecode output should be; any optimize > 0 does /// not emit assert statements diff --git a/crates/codegen/src/error.rs b/crates/codegen/src/error.rs index 5bd7c7ecaf0..9f1dcc27058 100644 --- a/crates/codegen/src/error.rs +++ b/crates/codegen/src/error.rs @@ -3,7 +3,7 @@ use core::fmt::Display; use rustpython_compiler_core::SourceLocation; use thiserror::Error; -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub enum PatternUnreachableReason { NameCapture, Wildcard, diff --git a/crates/codegen/src/ir.rs b/crates/codegen/src/ir.rs index 93cc784bd71..0d2e589008c 100644 --- a/crates/codegen/src/ir.rs +++ b/crates/codegen/src/ir.rs @@ -85,7 +85,7 @@ impl ops::IndexMut for Vec { } } -#[derive(Debug, Clone)] +#[derive(Clone, Copy, Debug)] pub struct InstructionInfo { pub instr: AnyInstruction, pub arg: OpArg, @@ -95,8 +95,8 @@ pub struct InstructionInfo { pub except_handler: Option, } -/// Exception handler information for an instruction -#[derive(Debug, Clone)] +/// Exception handler information for an instruction. +#[derive(Clone, Copy, Debug)] pub struct ExceptHandlerInfo { /// Block to jump to when exception occurs pub handler_block: BlockIdx, diff --git a/crates/codegen/src/symboltable.rs b/crates/codegen/src/symboltable.rs index 513ad30a3e7..2b243262b3c 100644 --- a/crates/codegen/src/symboltable.rs +++ b/crates/codegen/src/symboltable.rs @@ -758,7 +758,7 @@ impl SymbolTableAnalyzer { } } -#[derive(Debug, Clone)] +#[derive(Clone, Copy, Debug)] enum SymbolUsage { Global, Nonlocal, diff --git a/crates/common/src/cformat.rs b/crates/common/src/cformat.rs index 24332396fdb..7b9609e90ae 100644 --- a/crates/common/src/cformat.rs +++ b/crates/common/src/cformat.rs @@ -14,7 +14,7 @@ use rustpython_literal::{float, format::Case}; use crate::wtf8::{CodePoint, Wtf8, Wtf8Buf}; -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum CFormatErrorType { UnmatchedKeyParentheses, MissingModuloSign, @@ -27,7 +27,7 @@ pub enum CFormatErrorType { // also contains how many chars the parsing function consumed pub type ParsingError = (CFormatErrorType, usize); -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub struct CFormatError { pub typ: CFormatErrorType, // FIXME pub index: usize, diff --git a/crates/common/src/encodings.rs b/crates/common/src/encodings.rs index d54581eb9ea..c2f139b6bb9 100644 --- a/crates/common/src/encodings.rs +++ b/crates/common/src/encodings.rs @@ -262,6 +262,7 @@ pub mod errors { use super::*; use core::fmt::Write; + #[derive(Clone, Copy)] pub struct Strict; impl EncodeErrorHandler for Strict { @@ -286,6 +287,7 @@ pub mod errors { } } + #[derive(Clone, Copy)] pub struct Ignore; impl EncodeErrorHandler for Ignore { @@ -310,6 +312,7 @@ pub mod errors { } } + #[derive(Clone, Copy)] pub struct Replace; impl EncodeErrorHandler for Replace { @@ -338,6 +341,7 @@ pub mod errors { } } + #[derive(Clone, Copy)] pub struct XmlCharRefReplace; impl EncodeErrorHandler for XmlCharRefReplace { @@ -358,6 +362,7 @@ pub mod errors { } } + #[derive(Clone, Copy)] pub struct BackslashReplace; impl EncodeErrorHandler for BackslashReplace { @@ -394,6 +399,7 @@ pub mod errors { } } + #[derive(Clone, Copy)] pub struct NameReplace; impl EncodeErrorHandler for NameReplace { @@ -422,6 +428,7 @@ pub mod errors { } } + #[derive(Clone, Copy)] pub struct SurrogateEscape; impl EncodeErrorHandler for SurrogateEscape { diff --git a/crates/common/src/fileutils.rs b/crates/common/src/fileutils.rs index 7170b270d95..af9e5ad2d96 100644 --- a/crates/common/src/fileutils.rs +++ b/crates/common/src/fileutils.rs @@ -46,7 +46,7 @@ pub mod windows { pub const SECS_BETWEEN_EPOCHS: i64 = 11644473600; // Seconds between 1.1.1601 and 1.1.1970 - #[derive(Default)] + #[derive(Clone, Copy, Default)] pub struct StatStruct { pub st_dev: libc::c_ulong, pub st_ino: u64, @@ -256,6 +256,7 @@ pub mod windows { m as _ } + #[derive(Clone, Copy)] #[repr(C)] pub struct FILE_STAT_BASIC_INFORMATION { pub FileId: i64, @@ -275,8 +276,9 @@ pub mod windows { pub FileId128: [u64; 2], } - #[repr(C)] #[allow(dead_code)] + #[derive(Clone, Copy)] + #[repr(C)] pub enum FILE_INFO_BY_NAME_CLASS { FileStatByNameInfo, FileStatLxByNameInfo, diff --git a/crates/common/src/format.rs b/crates/common/src/format.rs index 1afee519aef..2842bd0a3d4 100644 --- a/crates/common/src/format.rs +++ b/crates/common/src/format.rs @@ -110,7 +110,7 @@ impl FormatParse for FormatSign { } } -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum FormatGrouping { Comma, Underscore, @@ -136,7 +136,7 @@ impl From<&FormatGrouping> for char { } } -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum FormatType { String, Binary, @@ -199,7 +199,7 @@ impl FormatParse for FormatType { } } -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub struct FormatSpec { conversion: Option, fill: Option, @@ -845,7 +845,7 @@ impl Deref for AsciiStr<'_> { } } -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum FormatSpecError { DecimalDigitsTooMany, PrecisionTooBig, @@ -862,7 +862,7 @@ pub enum FormatSpecError { NotImplemented(char, &'static str), } -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum FormatParseError { UnmatchedBracket, MissingStartBracket, diff --git a/crates/common/src/hash.rs b/crates/common/src/hash.rs index 40c428d89e3..f8f3783d224 100644 --- a/crates/common/src/hash.rs +++ b/crates/common/src/hash.rs @@ -25,6 +25,7 @@ pub const SEED_BITS: usize = core::mem::size_of::() * 2 * 8; // pub const CUTOFF: usize = 7; +#[derive(Clone, Copy)] pub struct HashSecret { k0: u64, k1: u64, diff --git a/crates/common/src/int.rs b/crates/common/src/int.rs index 57696e21fe7..9cfe2e0d738 100644 --- a/crates/common/src/int.rs +++ b/crates/common/src/int.rs @@ -29,7 +29,7 @@ pub fn float_to_ratio(value: f64) -> Option<(BigInt, BigInt)> { }) } -#[derive(Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum BytesToIntError { InvalidLiteral { base: u32 }, InvalidBase, diff --git a/crates/common/src/lock/cell_lock.rs b/crates/common/src/lock/cell_lock.rs index 73d722a8fdb..0e045c5950b 100644 --- a/crates/common/src/lock/cell_lock.rs +++ b/crates/common/src/lock/cell_lock.rs @@ -201,10 +201,14 @@ fn deadlock(lock_kind: &str, ty: &str) -> ! { panic!("deadlock: tried to {lock_kind}lock a Cell{ty} twice") } +#[derive(Clone, Copy)] pub struct SingleThreadId(()); + unsafe impl GetThreadId for SingleThreadId { const INIT: Self = Self(()); + fn nonzero_thread_id(&self) -> NonZero { - NonZero::new(1).unwrap() + // Safety: This is constant. + unsafe { NonZero::new_unchecked(1) } } } diff --git a/crates/common/src/lock/thread_mutex.rs b/crates/common/src/lock/thread_mutex.rs index 67ffc89245d..ec10ab1f181 100644 --- a/crates/common/src/lock/thread_mutex.rs +++ b/crates/common/src/lock/thread_mutex.rs @@ -121,19 +121,23 @@ impl ThreadMutex { } } } -// Whether ThreadMutex::try_lock failed because the mutex was already locked on another thread or -// on the current thread + +#[derive(Clone, Copy)] pub enum TryLockThreadError { + /// Failed to lock because mutex was already locked on another thread. Other, + /// Failed to lock because mutex was already locked on current thread. Current, } struct LockedPlaceholder(&'static str); + impl fmt::Debug for LockedPlaceholder { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.0) } } + impl fmt::Debug for ThreadMutex { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.try_lock() { diff --git a/crates/common/src/str.rs b/crates/common/src/str.rs index 155012ed21f..a250c5865d3 100644 --- a/crates/common/src/str.rs +++ b/crates/common/src/str.rs @@ -449,6 +449,7 @@ pub fn to_ascii(value: &str) -> AsciiString { unsafe { AsciiString::from_ascii_unchecked(ascii) } } +#[derive(Clone, Copy)] pub struct UnicodeEscapeCodepoint(pub CodePoint); impl fmt::Display for UnicodeEscapeCodepoint { diff --git a/crates/compiler-core/src/bytecode.rs b/crates/compiler-core/src/bytecode.rs index 3657c3b1b09..79f3a985dc7 100644 --- a/crates/compiler-core/src/bytecode.rs +++ b/crates/compiler-core/src/bytecode.rs @@ -32,7 +32,7 @@ mod oparg; /// Exception table entry for zero-cost exception handling /// Format: (start, size, target, depth<<1|lasti) -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct ExceptionTableEntry { /// Start instruction offset (inclusive) pub start: u32, @@ -47,7 +47,7 @@ pub struct ExceptionTableEntry { } impl ExceptionTableEntry { - pub fn new(start: u32, end: u32, target: u32, depth: u16, push_lasti: bool) -> Self { + pub const fn new(start: u32, end: u32, target: u32, depth: u16, push_lasti: bool) -> Self { Self { start, end, diff --git a/crates/compiler-core/src/marshal.rs b/crates/compiler-core/src/marshal.rs index 6a6100ca003..decb25d5283 100644 --- a/crates/compiler-core/src/marshal.rs +++ b/crates/compiler-core/src/marshal.rs @@ -6,7 +6,7 @@ use rustpython_wtf8::Wtf8; pub const FORMAT_VERSION: u32 = 5; -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub enum MarshalError { /// Unexpected End Of File Eof, @@ -42,6 +42,7 @@ impl core::error::Error for MarshalError {} type Result = core::result::Result; +#[derive(Clone, Copy)] #[repr(u8)] enum Type { // Null = b'0', diff --git a/crates/compiler-core/src/mode.rs b/crates/compiler-core/src/mode.rs index f2b19d677be..181ea4fdfe7 100644 --- a/crates/compiler-core/src/mode.rs +++ b/crates/compiler-core/src/mode.rs @@ -22,7 +22,7 @@ impl core::str::FromStr for Mode { } /// Returned when a given mode is not valid. -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub struct ModeParseError; impl core::fmt::Display for ModeParseError { diff --git a/crates/sre_engine/src/constants.rs b/crates/sre_engine/src/constants.rs index d90c08cb374..b38ecb109b8 100644 --- a/crates/sre_engine/src/constants.rs +++ b/crates/sre_engine/src/constants.rs @@ -14,9 +14,10 @@ use bitflags::bitflags; pub const SRE_MAGIC: usize = 20230612; -#[derive(num_enum::TryFromPrimitive, Debug, PartialEq, Eq)] -#[repr(u32)] + #[allow(non_camel_case_types, clippy::upper_case_acronyms)] +#[derive(num_enum::TryFromPrimitive, Copy, Clone, Debug, PartialEq, Eq)] +#[repr(u32)] pub enum SreOpcode { FAILURE = 0, SUCCESS = 1, @@ -63,9 +64,9 @@ pub enum SreOpcode { RANGE_UNI_IGNORE = 42, } -#[derive(num_enum::TryFromPrimitive, Debug, PartialEq, Eq)] -#[repr(u32)] #[allow(non_camel_case_types, clippy::upper_case_acronyms)] +#[derive(num_enum::TryFromPrimitive, Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u32)] pub enum SreAtCode { BEGINNING = 0, BEGINNING_LINE = 1, @@ -81,9 +82,9 @@ pub enum SreAtCode { UNI_NON_BOUNDARY = 11, } -#[derive(num_enum::TryFromPrimitive, Debug)] -#[repr(u32)] #[allow(non_camel_case_types, clippy::upper_case_acronyms)] +#[derive(num_enum::TryFromPrimitive, Clone, Copy, Debug)] +#[repr(u32)] pub enum SreCatCode { DIGIT = 0, NOT_DIGIT = 1, @@ -120,6 +121,7 @@ bitflags! { } bitflags! { + #[derive(Clone, Copy)] pub struct SreInfo: u32 { const PREFIX = 1; const LITERAL = 2; diff --git a/crates/vm/src/anystr.rs b/crates/vm/src/anystr.rs index 79b62a58abf..c44fc36c454 100644 --- a/crates/vm/src/anystr.rs +++ b/crates/vm/src/anystr.rs @@ -16,13 +16,13 @@ pub struct SplitArgs { maxsplit: isize, } -#[derive(FromArgs)] +#[derive(Clone, Copy, FromArgs)] pub struct SplitLinesArgs { #[pyarg(any, default = false)] pub keepends: bool, } -#[derive(FromArgs)] +#[derive(Clone, Copy, FromArgs)] pub struct ExpandTabsArgs { #[pyarg(any, default = 8)] tabsize: isize, diff --git a/crates/vm/src/builtins/descriptor.rs b/crates/vm/src/builtins/descriptor.rs index 89dafdd14b7..b0bb3a46c22 100644 --- a/crates/vm/src/builtins/descriptor.rs +++ b/crates/vm/src/builtins/descriptor.rs @@ -168,7 +168,7 @@ impl Representable for PyMethodDescriptor { } } -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub enum MemberKind { Bool = 14, ObjectEx = 16, @@ -176,11 +176,13 @@ pub enum MemberKind { pub type MemberSetterFunc = Option PyResult<()>>; +#[derive(Clone, Copy)] pub enum MemberGetter { Getter(fn(&VirtualMachine, PyObjectRef) -> PyResult), Offset(usize), } +#[derive(Clone, Copy)] pub enum MemberSetter { Setter(MemberSetterFunc), Offset(usize), diff --git a/crates/vm/src/builtins/module.rs b/crates/vm/src/builtins/module.rs index 60ffb1487fa..8286471a767 100644 --- a/crates/vm/src/builtins/module.rs +++ b/crates/vm/src/builtins/module.rs @@ -9,7 +9,7 @@ use crate::{ }; #[pyclass(module = false, name = "module")] -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub struct PyModuleDef { // pub index: usize, pub name: &'static PyStrInterned, @@ -26,7 +26,7 @@ pub type ModuleCreate = fn(&VirtualMachine, &PyObject, &'static PyModuleDef) -> PyResult>; pub type ModuleExec = fn(&VirtualMachine, &Py) -> PyResult<()>; -#[derive(Default)] +#[derive(Clone, Copy, Default)] pub struct PyModuleSlots { pub create: Option, pub exec: Option, @@ -83,7 +83,7 @@ impl PyModuleDef { #[allow(clippy::new_without_default)] // avoid Default implementation #[pyclass(module = false, name = "module")] -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub struct PyModule { // PyObject *md_dict; pub def: Option<&'static PyModuleDef>, diff --git a/crates/vm/src/builtins/namespace.rs b/crates/vm/src/builtins/namespace.rs index 2cc1693302a..5cd699aca33 100644 --- a/crates/vm/src/builtins/namespace.rs +++ b/crates/vm/src/builtins/namespace.rs @@ -14,8 +14,8 @@ use crate::{ /// /// SimpleNamespace(**kwargs) #[pyclass(module = "types", name = "SimpleNamespace")] -#[derive(Debug, Default)] -pub struct PyNamespace {} +#[derive(Copy, Clone, Debug, Default)] +pub struct PyNamespace; impl PyPayload for PyNamespace { #[inline] diff --git a/crates/vm/src/builtins/object.rs b/crates/vm/src/builtins/object.rs index eb9d226acb4..54abd327884 100644 --- a/crates/vm/src/builtins/object.rs +++ b/crates/vm/src/builtins/object.rs @@ -18,7 +18,7 @@ use itertools::Itertools; /// When called, it accepts no arguments and returns a new featureless /// instance that has no instance attributes and cannot be given any. #[pyclass(module = false, name = "object")] -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub struct PyBaseObject; impl PyPayload for PyBaseObject { diff --git a/crates/vm/src/builtins/singletons.rs b/crates/vm/src/builtins/singletons.rs index 169104efeb3..77d6c78bce2 100644 --- a/crates/vm/src/builtins/singletons.rs +++ b/crates/vm/src/builtins/singletons.rs @@ -9,7 +9,7 @@ use crate::{ }; #[pyclass(module = false, name = "NoneType")] -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub struct PyNone; impl PyPayload for PyNone { @@ -75,7 +75,7 @@ impl AsNumber for PyNone { } #[pyclass(module = false, name = "NotImplementedType")] -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub struct PyNotImplemented; impl PyPayload for PyNotImplemented { diff --git a/crates/vm/src/builtins/slice.rs b/crates/vm/src/builtins/slice.rs index 3aa23b0746c..5958aa58198 100644 --- a/crates/vm/src/builtins/slice.rs +++ b/crates/vm/src/builtins/slice.rs @@ -301,7 +301,7 @@ impl Representable for PySlice { } #[pyclass(module = false, name = "EllipsisType")] -#[derive(Debug)] +#[derive(Copy, Clone, Debug)] pub struct PyEllipsis; impl PyPayload for PyEllipsis { diff --git a/crates/vm/src/builtins/zip.rs b/crates/vm/src/builtins/zip.rs index ee3ecb57b27..0c939da35f7 100644 --- a/crates/vm/src/builtins/zip.rs +++ b/crates/vm/src/builtins/zip.rs @@ -24,7 +24,7 @@ impl PyPayload for PyZip { } } -#[derive(FromArgs)] +#[derive(Clone, Copy, FromArgs)] pub struct PyZipNewArgs { #[pyarg(named, optional)] strict: OptionalArg, diff --git a/crates/vm/src/dict_inner.rs b/crates/vm/src/dict_inner.rs index f2a379d99a5..e99c4a4e2c2 100644 --- a/crates/vm/src/dict_inner.rs +++ b/crates/vm/src/dict_inner.rs @@ -124,7 +124,7 @@ struct DictEntry { } static_assertions::assert_eq_size!(DictEntry, Option>); -#[derive(Debug, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct DictSize { indices_size: usize, pub entries_size: usize, diff --git a/crates/vm/src/function/method.rs b/crates/vm/src/function/method.rs index 6440fd801fc..f5dad58491d 100644 --- a/crates/vm/src/function/method.rs +++ b/crates/vm/src/function/method.rs @@ -63,7 +63,7 @@ macro_rules! define_methods { }; } -#[derive(Clone)] +#[derive(Clone, Copy)] pub struct PyMethodDef { pub name: &'static str, // TODO: interned pub func: &'static dyn PyNativeFn, @@ -270,7 +270,7 @@ impl core::fmt::Debug for PyMethodDef { // This is not a part of CPython API. // But useful to support dynamically generated methods #[pyclass(name, module = false, ctx = "method_def")] -#[derive(Debug)] +#[derive(Clone, Copy, Debug)] pub struct HeapMethodDef { method: PyMethodDef, } diff --git a/crates/vm/src/function/number.rs b/crates/vm/src/function/number.rs index b53208bcd93..f1ac38fc553 100644 --- a/crates/vm/src/function/number.rs +++ b/crates/vm/src/function/number.rs @@ -14,7 +14,7 @@ use num_traits::PrimInt; /// method, this method will first be called to convert the object into a float. /// If `__complex__()` is not defined then it falls back to `__float__()`. If /// `__float__()` is not defined it falls back to `__index__()`. -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] #[repr(transparent)] pub struct ArgIntoComplex { value: Complex64, @@ -52,7 +52,7 @@ impl TryFromObject for ArgIntoComplex { /// If the object is not a Python floating point object but has a `__float__()` /// method, this method will first be called to convert the object into a float. /// If `__float__()` is not defined then it falls back to `__index__()`. -#[derive(Debug, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] #[repr(transparent)] pub struct ArgIntoFloat { value: f64, @@ -95,7 +95,7 @@ impl TryFromObject for ArgIntoFloat { /// By default an object is considered true unless its class defines either a /// `__bool__()` method that returns False or a `__len__()` method that returns /// zero, when called with the object. -#[derive(Debug, Default, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub struct ArgIntoBool { value: bool, } diff --git a/crates/vm/src/protocol/buffer.rs b/crates/vm/src/protocol/buffer.rs index 0fe4d15458b..34fe56ae549 100644 --- a/crates/vm/src/protocol/buffer.rs +++ b/crates/vm/src/protocol/buffer.rs @@ -14,6 +14,7 @@ use alloc::borrow::Cow; use core::{fmt::Debug, ops::Range}; use itertools::Itertools; +#[derive(Clone, Copy)] pub struct BufferMethods { pub obj_bytes: fn(&PyBuffer) -> BorrowedValue<'_, [u8]>, pub obj_bytes_mut: fn(&PyBuffer) -> BorrowedValueMut<'_, [u8]>, diff --git a/crates/vm/src/protocol/mapping.rs b/crates/vm/src/protocol/mapping.rs index 6c200043e35..e7af8e53be7 100644 --- a/crates/vm/src/protocol/mapping.rs +++ b/crates/vm/src/protocol/mapping.rs @@ -48,7 +48,7 @@ impl PyMappingSlots { } #[allow(clippy::type_complexity)] -#[derive(Default)] +#[derive(Clone, Copy, Default)] pub struct PyMappingMethods { pub length: Option, &VirtualMachine) -> PyResult>, pub subscript: Option, &PyObject, &VirtualMachine) -> PyResult>, diff --git a/crates/vm/src/protocol/sequence.rs b/crates/vm/src/protocol/sequence.rs index cee46a29089..f3d7f644ffc 100644 --- a/crates/vm/src/protocol/sequence.rs +++ b/crates/vm/src/protocol/sequence.rs @@ -70,7 +70,7 @@ impl PySequenceSlots { } #[allow(clippy::type_complexity)] -#[derive(Default)] +#[derive(Clone, Copy, Default)] pub struct PySequenceMethods { pub length: Option, &VirtualMachine) -> PyResult>, pub concat: Option, &PyObject, &VirtualMachine) -> PyResult>, diff --git a/crates/vm/src/sliceable.rs b/crates/vm/src/sliceable.rs index e416f5a1b49..3be8c7629ca 100644 --- a/crates/vm/src/sliceable.rs +++ b/crates/vm/src/sliceable.rs @@ -252,6 +252,7 @@ impl SliceableSequenceOp for [T] { } } +#[derive(Clone, Copy)] pub enum SequenceIndex { Int(isize), Slice(SaturatedSlice), @@ -403,6 +404,7 @@ impl SaturatedSlice { } } +#[derive(Clone, Copy)] pub struct SaturatedSliceIter { index: isize, step: isize, diff --git a/crates/vm/src/stdlib/marshal.rs b/crates/vm/src/stdlib/marshal.rs index cf7abe65194..53a0b4b2864 100644 --- a/crates/vm/src/stdlib/marshal.rs +++ b/crates/vm/src/stdlib/marshal.rs @@ -25,6 +25,7 @@ mod decl { #[pyattr(name = "version")] use marshal::FORMAT_VERSION; + #[derive(Clone, Copy)] pub struct DumpError; impl marshal::Dumpable for PyObjectRef { diff --git a/crates/vm/src/stdlib/os.rs b/crates/vm/src/stdlib/os.rs index 691cb068605..f492c9a2627 100644 --- a/crates/vm/src/stdlib/os.rs +++ b/crates/vm/src/stdlib/os.rs @@ -35,7 +35,7 @@ impl crate::convert::IntoPyException for rustix::io::Errno { } #[allow(dead_code)] -#[derive(FromArgs, Default)] +#[derive(FromArgs, Default, Copy, Clone)] pub struct TargetIsDirectory { #[pyarg(any, default = false)] pub(crate) target_is_directory: bool, diff --git a/crates/vm/src/stdlib/typevar.rs b/crates/vm/src/stdlib/typevar.rs index 28706ac425b..e3d3958ca04 100644 --- a/crates/vm/src/stdlib/typevar.rs +++ b/crates/vm/src/stdlib/typevar.rs @@ -988,9 +988,9 @@ pub(crate) mod typevar { #[pyattr] #[pyclass(name = "Generic", module = "typing")] - #[derive(Debug, PyPayload)] + #[derive(Copy, Clone, Debug, PyPayload)] #[allow(dead_code)] - pub struct Generic {} + pub struct Generic; #[pyclass(flags(BASETYPE))] impl Generic { diff --git a/crates/vm/src/stdlib/typing.rs b/crates/vm/src/stdlib/typing.rs index 6938bca8bbb..c82ff3dbb54 100644 --- a/crates/vm/src/stdlib/typing.rs +++ b/crates/vm/src/stdlib/typing.rs @@ -49,7 +49,7 @@ pub(crate) mod decl { } #[pyclass(no_attr, name = "NoDefaultType", module = "typing")] - #[derive(Debug, PyPayload)] + #[derive(Clone, Copy, Debug, PyPayload)] pub struct NoDefault; #[pyclass(with(Constructor, Representable), flags(BASETYPE))] diff --git a/crates/wasm/src/vm_class.rs b/crates/wasm/src/vm_class.rs index 6baef990d1e..c6f1318e692 100644 --- a/crates/wasm/src/vm_class.rs +++ b/crates/wasm/src/vm_class.rs @@ -102,6 +102,7 @@ pub(crate) fn weak_vm(vm: &VirtualMachine) -> Weak { STORED_VMS.with_borrow(|vms| Rc::downgrade(vms.get(id).expect("VirtualMachine is not valid"))) } +#[derive(Clone, Copy)] #[wasm_bindgen(js_name = vmStore)] pub struct VMStore; From 2c2b13784eea02489a739cf32abfebedfafd9beb Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Fri, 23 Jan 2026 15:41:33 +0200 Subject: [PATCH 3/3] Clippy --- crates/codegen/src/ir.rs | 6 +++--- examples/dis.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/codegen/src/ir.rs b/crates/codegen/src/ir.rs index 0d2e589008c..b1534a4f2c1 100644 --- a/crates/codegen/src/ir.rs +++ b/crates/codegen/src/ir.rs @@ -742,13 +742,13 @@ fn generate_exception_table(blocks: &[Block], block_to_index: &[u32]) -> Box<[u8 // instr_size includes EXTENDED_ARG instructions let instr_size = instr.arg.instr_size() as u32; - match (¤t_entry, &instr.except_handler) { + match (¤t_entry, instr.except_handler) { // No current entry, no handler - nothing to do (None, None) => {} // No current entry, handler starts - begin new entry (None, Some(handler)) => { - current_entry = Some((handler.clone(), instr_index)); + current_entry = Some((handler, instr_index)); } // Current entry exists, same handler - continue @@ -767,7 +767,7 @@ fn generate_exception_table(blocks: &[Block], block_to_index: &[u32]) -> Box<[u8 curr_handler.stack_depth as u16, curr_handler.preserve_lasti, )); - current_entry = Some((handler.clone(), instr_index)); + current_entry = Some((handler, instr_index)); } // Current entry exists, no handler - finish current entry diff --git a/examples/dis.rs b/examples/dis.rs index 1ca350603f9..0b6190dde3c 100644 --- a/examples/dis.rs +++ b/examples/dis.rs @@ -60,7 +60,7 @@ fn main() -> Result<(), lexopt::Error> { for script in &scripts { if script.exists() && script.is_file() { - let res = display_script(script, mode, opts.clone(), expand_code_objects); + let res = display_script(script, mode, opts, expand_code_objects); if let Err(e) = res { error!("Error while compiling {script:?}: {e}"); }