Suppress .clone() suggestion inside derive macro expansions

This commit is contained in:
lapla
2026-03-01 22:49:56 +09:00
parent 765fd2d8c7
commit 3cecc8d003
4 changed files with 40 additions and 37 deletions
@@ -28,7 +28,7 @@
use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::hygiene::DesugaringKind;
use rustc_span::{BytePos, Ident, Span, Symbol, kw, sym};
use rustc_span::{BytePos, ExpnKind, Ident, MacroKind, Span, Symbol, kw, sym};
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
use rustc_trait_selection::error_reporting::traits::FindExprBySpan;
use rustc_trait_selection::error_reporting::traits::call_kind::CallKind;
@@ -1438,6 +1438,12 @@ fn suggest_cloning_inner(
expr: &hir::Expr<'_>,
) -> bool {
let tcx = self.infcx.tcx;
// Don't suggest `.clone()` in a derive macro expansion.
if let ExpnKind::Macro(MacroKind::Derive, _) = self.body.span.ctxt().outer_expn_data().kind
{
return false;
}
if let Some(_) = self.clone_on_reference(expr) {
// Avoid redundant clone suggestion already suggested in `explain_captures`.
// See `tests/ui/moves/needs-clone-through-deref.rs`
@@ -7,10 +7,6 @@ LL | struct StructA(String);
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(Debug)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -21,10 +17,6 @@ LL | struct StructA(String);
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -36,10 +28,6 @@ LL | struct StructA(String);
|
= note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -50,10 +38,6 @@ LL | struct StructA(String);
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(PartialOrd)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -65,10 +49,6 @@ LL | struct StructA(String);
|
= note: `#[derive(PartialOrd)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -79,10 +59,6 @@ LL | struct StructA(String);
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(Ord)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -94,10 +70,6 @@ LL | struct StructA(String);
|
= note: `#[derive(Ord)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -108,10 +80,6 @@ LL | struct StructA(String);
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(Hash)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:13:16
@@ -122,10 +90,6 @@ LL | struct StructA(String);
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(Clone)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
help: consider cloning the value if the performance cost is acceptable
|
LL | struct StructA(String.clone());
| ++++++++
error[E0507]: cannot move out of `self` which is behind a shared reference
--> $DIR/deriving-with-repr-packed-move-errors.rs:28:9
@@ -0,0 +1,9 @@
// Test for https://github.com/rust-lang/rust/issues/153126
#[repr(packed, C)]
#[derive(PartialEq)]
struct Thing(u8, String);
//~^ ERROR cannot move out of a shared reference
//~| ERROR cannot move out of a shared reference
fn main() {}
@@ -0,0 +1,24 @@
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-no-clone-suggestion.rs:5:18
|
LL | #[derive(PartialEq)]
| --------- in this derive macro expansion
LL | struct Thing(u8, String);
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
error[E0507]: cannot move out of a shared reference
--> $DIR/deriving-with-repr-packed-no-clone-suggestion.rs:5:18
|
LL | #[derive(PartialEq)]
| --------- in this derive macro expansion
LL | struct Thing(u8, String);
| ^^^^^^ move occurs because value has type `String`, which does not implement the `Copy` trait
|
= note: `#[derive(PartialEq)]` triggers a move because taking references to the fields of a packed struct is undefined behaviour
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0507`.