about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTimo <30553356+y21@users.noreply.github.com>2025-04-12 16:50:12 +0000
committerGitHub <noreply@github.com>2025-04-12 16:50:12 +0000
commit8dfcaa0590a29ba8d5ddea87cd57d61e5c9224f7 (patch)
tree42f056904f9843bbd07e914c50c9f79a4f5cd66a
parent3f6025a11de0db7a791fd29b3b202c64703a5544 (diff)
parent315ea9590dc06d0293573a918239377c8c487de8 (diff)
downloadrust-8dfcaa0590a29ba8d5ddea87cd57d61e5c9224f7.tar.gz
rust-8dfcaa0590a29ba8d5ddea87cd57d61e5c9224f7.zip
Do not propose to auto-derive `Clone` in presence of unsafe fields (#14559)
`unsafe_fields` is an incomplete feature; comments have been put near
`#![expect(incomplete_features)]` to ensure that we revisit the
situation when the feature becomes complete.

changelog: [`expl_impl_clone_on_copy`]: do not lint in the presence of
`unsafe` fields

Fixes #14558
-rw-r--r--clippy_lints/src/derive.rs4
-rw-r--r--tests/ui/derive.rs17
-rw-r--r--tests/ui/derive.stderr20
3 files changed, 31 insertions, 10 deletions
diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs
index a109ee9f64b..06528f875a2 100644
--- a/clippy_lints/src/derive.rs
+++ b/clippy_lints/src/derive.rs
@@ -349,6 +349,10 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h
     {
         return;
     }
+    // The presence of `unsafe` fields prevents deriving `Clone` automatically
+    if ty_adt.all_fields().any(|f| f.safety.is_unsafe()) {
+        return;
+    }
 
     span_lint_and_note(
         cx,
diff --git a/tests/ui/derive.rs b/tests/ui/derive.rs
index 75d888c3107..2c5fa0be975 100644
--- a/tests/ui/derive.rs
+++ b/tests/ui/derive.rs
@@ -6,6 +6,8 @@
     dead_code
 )]
 #![warn(clippy::expl_impl_clone_on_copy)]
+#![expect(incomplete_features)] // `unsafe_fields` is incomplete for the time being
+#![feature(unsafe_fields)] // `clone()` cannot be derived automatically on unsafe fields
 
 #[derive(Copy)]
 struct Qux;
@@ -112,4 +114,19 @@ impl<T: Copy> Clone for Packed<T> {
     }
 }
 
+fn issue14558() {
+    pub struct Valid {
+        pub unsafe actual: (),
+    }
+
+    unsafe impl Copy for Valid {}
+
+    impl Clone for Valid {
+        #[inline]
+        fn clone(&self) -> Self {
+            *self
+        }
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/derive.stderr b/tests/ui/derive.stderr
index bda8800e80a..ff2c24ff48e 100644
--- a/tests/ui/derive.stderr
+++ b/tests/ui/derive.stderr
@@ -1,5 +1,5 @@
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:13:1
+  --> tests/ui/derive.rs:15:1
    |
 LL | / impl Clone for Qux {
 LL | |
@@ -10,7 +10,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:13:1
+  --> tests/ui/derive.rs:15:1
    |
 LL | / impl Clone for Qux {
 LL | |
@@ -23,7 +23,7 @@ LL | | }
    = help: to override `-D warnings` add `#[allow(clippy::expl_impl_clone_on_copy)]`
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:39:1
+  --> tests/ui/derive.rs:41:1
    |
 LL | / impl<'a> Clone for Lt<'a> {
 LL | |
@@ -34,7 +34,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:39:1
+  --> tests/ui/derive.rs:41:1
    |
 LL | / impl<'a> Clone for Lt<'a> {
 LL | |
@@ -45,7 +45,7 @@ LL | | }
    | |_^
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:52:1
+  --> tests/ui/derive.rs:54:1
    |
 LL | / impl Clone for BigArray {
 LL | |
@@ -56,7 +56,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:52:1
+  --> tests/ui/derive.rs:54:1
    |
 LL | / impl Clone for BigArray {
 LL | |
@@ -67,7 +67,7 @@ LL | | }
    | |_^
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:65:1
+  --> tests/ui/derive.rs:67:1
    |
 LL | / impl Clone for FnPtr {
 LL | |
@@ -78,7 +78,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:65:1
+  --> tests/ui/derive.rs:67:1
    |
 LL | / impl Clone for FnPtr {
 LL | |
@@ -89,7 +89,7 @@ LL | | }
    | |_^
 
 error: you are implementing `Clone` explicitly on a `Copy` type
-  --> tests/ui/derive.rs:87:1
+  --> tests/ui/derive.rs:89:1
    |
 LL | / impl<T: Clone> Clone for Generic2<T> {
 LL | |
@@ -100,7 +100,7 @@ LL | | }
    | |_^
    |
 note: consider deriving `Clone` or removing `Copy`
-  --> tests/ui/derive.rs:87:1
+  --> tests/ui/derive.rs:89:1
    |
 LL | / impl<T: Clone> Clone for Generic2<T> {
 LL | |