diff --git a/Cargo.toml b/Cargo.toml index 81bbdebeb39..c4f7135c17f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -402,6 +402,7 @@ iter_filter_is_some = "warn" manual_is_variant_and = "warn" map_unwrap_or = "warn" match_bool = "warn" +mismatching_type_param_order = "warn" must_use_candidate = "warn" mut_mut = "warn" needless_bitwise_bool = "warn" @@ -409,6 +410,7 @@ needless_for_each = "warn" option_as_ref_cloned = "warn" ptr_offset_by_literal = "warn" redundant_else = "warn" +ref_option = "warn" return_self_not_must_use = "warn" uninlined_format_args = "warn" unnecessary_wraps = "warn" diff --git a/crates/derive-impl/src/compile_bytecode.rs b/crates/derive-impl/src/compile_bytecode.rs index 05197440e69..842b21f07f1 100644 --- a/crates/derive-impl/src/compile_bytecode.rs +++ b/crates/derive-impl/src/compile_bytecode.rs @@ -227,7 +227,7 @@ impl PyCompileArgs { let mut source: Option = None; let mut crate_name = None; - fn assert_source_empty(source: &Option) -> Result<(), syn::Error> { + fn assert_source_empty(source: Option<&CompilationSource>) -> Result<(), syn::Error> { if let Some(source) = source { Err(syn::Error::new( source.span.0, @@ -263,14 +263,14 @@ impl PyCompileArgs { } else if ident == "module_name" { module_name = Some(check_str()?.value()) } else if ident == "source" { - assert_source_empty(&source)?; + assert_source_empty(source.as_ref())?; let code = check_str()?.value(); source = Some(CompilationSource { kind: CompilationSourceKind::SourceCode(code), span: (ident.span(), meta.input.cursor().span()), }); } else if ident == "file" { - assert_source_empty(&source)?; + assert_source_empty(source.as_ref())?; let (base, rel_path) = str_path()?; source = Some(CompilationSource { kind: CompilationSourceKind::File { base, rel_path }, @@ -281,7 +281,7 @@ impl PyCompileArgs { bail_span!(ident, "py_compile doesn't accept dir") } - assert_source_empty(&source)?; + assert_source_empty(source.as_ref())?; let (base, rel_path) = str_path()?; source = Some(CompilationSource { kind: CompilationSourceKind::Dir { base, rel_path }, diff --git a/crates/stdlib/src/socket.rs b/crates/stdlib/src/socket.rs index ecc4add0cba..e3ce52b943a 100644 --- a/crates/stdlib/src/socket.rs +++ b/crates/stdlib/src/socket.rs @@ -1085,7 +1085,7 @@ mod _socket { loop { if deadline.is_some() || matches!(wait_kind, SockWaitKind::Connect) { let sock = self.sock()?; - sock_wait_deadline(&sock, wait_kind, &deadline, vm)?; + sock_wait_deadline(&sock, wait_kind, deadline.as_ref(), vm)?; } let err = loop { @@ -2452,7 +2452,7 @@ mod _socket { timeout: Option, vm: &VirtualMachine, ) -> PyResult { - match sock_wait_deadline(sock, wait_kind, &timeout.map(Deadline::new), vm) { + match sock_wait_deadline(sock, wait_kind, timeout.map(Deadline::new).as_ref(), vm) { Ok(()) => Ok(false), Err(IoOrPyException::Timeout) => Ok(true), Err(e) => Err(e.into_pyexception(vm)), @@ -2463,7 +2463,7 @@ mod _socket { fn sock_wait_deadline( sock: &Socket, wait_kind: SockWaitKind, - deadline: &Option, + deadline: Option<&Deadline>, vm: &VirtualMachine, ) -> Result<(), IoOrPyException> { #[cfg(unix)] diff --git a/crates/vm/src/builtins/module.rs b/crates/vm/src/builtins/module.rs index 51d90e9b32e..90410907276 100644 --- a/crates/vm/src/builtins/module.rs +++ b/crates/vm/src/builtins/module.rs @@ -180,7 +180,7 @@ impl Py { .flatten() .filter(|s| !vm.is_none(s)); - let origin = get_spec_file_origin(&spec, vm); + let origin = get_spec_file_origin(spec.as_ref(), vm); let is_possibly_shadowing = origin .as_ref() diff --git a/crates/vm/src/builtins/type.rs b/crates/vm/src/builtins/type.rs index b3980c2c789..d26c81a7b76 100644 --- a/crates/vm/src/builtins/type.rs +++ b/crates/vm/src/builtins/type.rs @@ -806,8 +806,8 @@ impl PyType { // Note: inherit_slots is called in PyClassImpl::init_class after // slots are fully initialized by make_slots() - Self::set_new(&new_type.slots, &new_type.base); - Self::set_alloc(&new_type.slots, &new_type.base); + Self::set_new(&new_type.slots, new_type.base.as_ref()); + Self::set_alloc(&new_type.slots, new_type.base.as_ref()); let weakref_type = super::PyWeak::static_type(); for base in new_type.bases.read().iter() { @@ -853,25 +853,23 @@ impl PyType { self.update_slot::(attr_name, ctx); } - Self::set_new(&self.slots, &self.base); - Self::set_alloc(&self.slots, &self.base); + Self::set_new(&self.slots, self.base.as_ref()); + Self::set_alloc(&self.slots, self.base.as_ref()); } - fn set_new(slots: &PyTypeSlots, base: &Option) { + fn set_new(slots: &PyTypeSlots, base: Option<&PyTypeRef>) { if slots.flags.contains(PyTypeFlags::DISALLOW_INSTANTIATION) { slots.new.store(None) } else if slots.new.load().is_none() { - slots - .new - .store(base.as_ref().and_then(|base| base.slots.new.load())) + slots.new.store(base.and_then(|base| base.slots.new.load())) } } - fn set_alloc(slots: &PyTypeSlots, base: &Option) { + fn set_alloc(slots: &PyTypeSlots, base: Option<&PyTypeRef>) { if slots.alloc.load().is_none() { slots .alloc - .store(base.as_ref().and_then(|base| base.slots.alloc.load())); + .store(base.and_then(|base| base.slots.alloc.load())); } } diff --git a/crates/vm/src/frame.rs b/crates/vm/src/frame.rs index fe00787181b..7050d851743 100644 --- a/crates/vm/src/frame.rs +++ b/crates/vm/src/frame.rs @@ -340,11 +340,11 @@ impl LocalsPlus { /// Get a reference to a stack slot by index from the bottom. #[inline(always)] - fn stack_index(&self, idx: usize) -> &Option { + fn stack_index(&self, idx: usize) -> Option<&PyStackRef> { debug_assert!(idx < self.stack_top as usize); let data = self.data_as_slice(); let raw_idx = self.nlocalsplus as usize + idx; - unsafe { &*(data.as_ptr().add(raw_idx) as *const Option) } + unsafe { (*(data.as_ptr().add(raw_idx) as *const Option)).as_ref() } } /// Get a mutable reference to a stack slot by index from the bottom. @@ -358,7 +358,7 @@ impl LocalsPlus { /// Get the last stack element (top of stack). #[inline(always)] - fn stack_last(&self) -> Option<&Option> { + fn stack_last(&self) -> Option> { if self.stack_top == 0 { None } else { @@ -2343,8 +2343,8 @@ impl ExecutingFrame<'_> { let idx = index.get(arg) as usize; let stack_len = self.localsplus.stack_len(); debug_assert!(stack_len >= idx, "CopyItem: stack underflow"); - let value = self.localsplus.stack_index(stack_len - idx).clone(); - self.push_stackref_opt(value); + let value = self.localsplus.stack_index(stack_len - idx); + self.push_stackref_opt(value.cloned()); Ok(None) } Instruction::CopyFreeVars { n } => { @@ -3567,10 +3567,10 @@ impl ExecutingFrame<'_> { let stack_len = self.localsplus.stack_len(); let exit_func = expect_unchecked( - self.localsplus.stack_index(stack_len - 5).clone(), + self.localsplus.stack_index(stack_len - 5), "WithExceptStart: exit_func is NULL", ); - let self_or_null = self.localsplus.stack_index(stack_len - 4).clone(); + let self_or_null = self.localsplus.stack_index(stack_len - 4); let (tp, val, tb) = if let Some(ref exc) = exc { vm.split_exception(exc.clone()) @@ -3579,7 +3579,7 @@ impl ExecutingFrame<'_> { }; let exit_res = if let Some(self_exit) = self_or_null { - exit_func.call((self_exit.to_pyobj(), tp, val, tb), vm)? + exit_func.call((self_exit.clone().to_pyobj(), tp, val, tb), vm)? } else { exit_func.call((tp, val, tb), vm)? }; @@ -6233,7 +6233,7 @@ impl ExecutingFrame<'_> { .ok() .filter(|s| !vm.is_none(s)); - let origin = get_spec_file_origin(&spec, vm); + let origin = get_spec_file_origin(spec.as_ref(), vm); let is_possibly_shadowing = origin .as_ref() diff --git a/crates/vm/src/getpath.rs b/crates/vm/src/getpath.rs index 63f922a6365..38aa122db49 100644 --- a/crates/vm/src/getpath.rs +++ b/crates/vm/src/getpath.rs @@ -132,15 +132,15 @@ pub fn init_path_config(settings: &Settings) -> Paths { }; // Step 2: Check for venv (pyvenv.cfg) and get 'home' - let (venv_prefix, home_dir) = detect_venv(&exe_dir); + let (venv_prefix, home_dir) = detect_venv(exe_dir.as_ref()); let search_dir = home_dir.clone().or(exe_dir); // Step 3: Check for build directory - let build_prefix = detect_build_directory(&search_dir); + let build_prefix = detect_build_directory(search_dir.as_ref()); // Step 4: Calculate prefix via landmark search // When in venv, search_dir is home_dir, so this gives us the base Python's prefix - let calculated_prefix = calculate_prefix(&search_dir, &build_prefix); + let calculated_prefix = calculate_prefix(search_dir.as_ref(), build_prefix.as_ref()); // Step 5: Set prefix and base_prefix if venv_prefix.is_some() { @@ -161,13 +161,13 @@ pub fn init_path_config(settings: &Settings) -> Paths { // In venv: exec_prefix = prefix (venv directory) paths.prefix.clone() } else { - calculate_exec_prefix(&search_dir, &paths.prefix) + calculate_exec_prefix(search_dir.as_ref(), paths.prefix.as_ref()) }; paths.base_exec_prefix = paths.base_prefix.clone(); // Step 7: Calculate base_executable (if not already set by __PYVENV_LAUNCHER__) if paths.base_executable.is_empty() { - paths.base_executable = calculate_base_executable(executable.as_ref(), &home_dir); + paths.base_executable = calculate_base_executable(executable.as_ref(), home_dir.as_ref()); } // Step 8: Build module_search_paths @@ -195,7 +195,7 @@ fn default_prefix() -> String { /// Detect virtual environment by looking for pyvenv.cfg /// Returns (venv_prefix, home_dir from pyvenv.cfg) -fn detect_venv(exe_dir: &Option) -> (Option, Option) { +fn detect_venv(exe_dir: Option<&PathBuf>) -> (Option, Option) { // Try exe_dir/../pyvenv.cfg first (standard venv layout: venv/bin/python) if let Some(dir) = exe_dir && let Some(venv_dir) = dir.parent() @@ -222,8 +222,8 @@ fn detect_venv(exe_dir: &Option) -> (Option, Option) } /// Detect if running from a build directory -fn detect_build_directory(exe_dir: &Option) -> Option { - let dir = exe_dir.as_ref()?; +fn detect_build_directory(exe_dir: Option<&PathBuf>) -> Option { + let dir = exe_dir?; // Check for pybuilddir.txt (indicates build directory) if dir.join(platform::BUILDDIR_TXT).exists() { @@ -240,7 +240,7 @@ fn detect_build_directory(exe_dir: &Option) -> Option { } /// Calculate prefix by searching for landmarks -fn calculate_prefix(exe_dir: &Option, build_prefix: &Option) -> String { +fn calculate_prefix(exe_dir: Option<&PathBuf>, build_prefix: Option<&PathBuf>) -> String { // 1. If build directory detected, use it if let Some(bp) = build_prefix { return bp.to_string_lossy().into_owned(); @@ -266,7 +266,7 @@ fn calculate_prefix(exe_dir: &Option, build_prefix: &Option) - } /// Calculate exec_prefix -fn calculate_exec_prefix(exe_dir: &Option, prefix: &str) -> String { +fn calculate_exec_prefix(exe_dir: Option<&PathBuf>, prefix: &str) -> String { #[cfg(windows)] { // Windows: exec_prefix == prefix @@ -289,7 +289,7 @@ fn calculate_exec_prefix(exe_dir: &Option, prefix: &str) -> String { } /// Calculate base_executable -fn calculate_base_executable(executable: Option<&PathBuf>, home_dir: &Option) -> String { +fn calculate_base_executable(executable: Option<&PathBuf>, home_dir: Option<&PathBuf>) -> String { // If in venv and we have home, construct base_executable from home if let (Some(exe), Some(home)) = (executable, home_dir) && let Some(exe_name) = exe.file_name() diff --git a/crates/vm/src/import.rs b/crates/vm/src/import.rs index d7e86422ec9..5c418b35d67 100644 --- a/crates/vm/src/import.rs +++ b/crates/vm/src/import.rs @@ -267,10 +267,11 @@ pub fn remove_importlib_frames(vm: &VirtualMachine, exc: &Py) { /// Get origin path from a module spec, checking has_location first. pub(crate) fn get_spec_file_origin( - spec: &Option, + spec: Option<&PyObjectRef>, vm: &VirtualMachine, ) -> Option { - let spec = spec.as_ref()?; + let spec = spec?; + let has_location = spec .get_attr("has_location", vm) .ok() diff --git a/crates/vm/src/stdlib/_ast/validate.rs b/crates/vm/src/stdlib/_ast/validate.rs index 9957fe4ee39..cad37d38610 100644 --- a/crates/vm/src/stdlib/_ast/validate.rs +++ b/crates/vm/src/stdlib/_ast/validate.rs @@ -279,7 +279,7 @@ fn validate_typeparam(vm: &VirtualMachine, tp: &ast::TypeParam) -> PyResult<()> fn validate_type_params( vm: &VirtualMachine, - type_params: &Option>, + type_params: Option<&ast::TypeParams>, ) -> PyResult<()> { if let Some(type_params) = type_params { for tp in &type_params.type_params { @@ -478,7 +478,7 @@ fn validate_stmt(vm: &VirtualMachine, stmt: &ast::Stmt) -> PyResult<()> { "FunctionDef" }; validate_body(vm, &func.body, owner)?; - validate_type_params(vm, &func.type_params)?; + validate_type_params(vm, func.type_params.as_deref())?; validate_parameters(vm, &func.parameters)?; validate_decorators(vm, &func.decorator_list)?; if let Some(returns) = &func.returns { @@ -488,7 +488,7 @@ fn validate_stmt(vm: &VirtualMachine, stmt: &ast::Stmt) -> PyResult<()> { } ast::Stmt::ClassDef(class_def) => { validate_body(vm, &class_def.body, "ClassDef")?; - validate_type_params(vm, &class_def.type_params)?; + validate_type_params(vm, class_def.type_params.as_deref())?; if let Some(arguments) = &class_def.arguments { validate_exprs(vm, &arguments.args, ast::ExprContext::Load, false)?; validate_keywords(vm, &arguments.keywords)?; @@ -525,7 +525,7 @@ fn validate_stmt(vm: &VirtualMachine, stmt: &ast::Stmt) -> PyResult<()> { return Err(vm.new_type_error("TypeAlias with non-Name name")); } validate_expr(vm, &alias.name, ast::ExprContext::Store)?; - validate_type_params(vm, &alias.type_params)?; + validate_type_params(vm, alias.type_params.as_deref())?; validate_expr(vm, &alias.value, ast::ExprContext::Load) } ast::Stmt::For(for_stmt) => {