diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7c12737776949..641121597848c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -28,7 +28,7 @@ use rustc_middle::ty::{ 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 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { 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` diff --git a/tests/ui/derives/deriving-with-repr-packed-move-errors.stderr b/tests/ui/derives/deriving-with-repr-packed-move-errors.stderr index 4b085425033d9..e857b308d531f 100644 --- a/tests/ui/derives/deriving-with-repr-packed-move-errors.stderr +++ b/tests/ui/derives/deriving-with-repr-packed-move-errors.stderr @@ -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 diff --git a/tests/ui/derives/deriving-with-repr-packed-no-clone-suggestion.rs b/tests/ui/derives/deriving-with-repr-packed-no-clone-suggestion.rs new file mode 100644 index 0000000000000..2fc9e47939501 --- /dev/null +++ b/tests/ui/derives/deriving-with-repr-packed-no-clone-suggestion.rs @@ -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() {} diff --git a/tests/ui/derives/deriving-with-repr-packed-no-clone-suggestion.stderr b/tests/ui/derives/deriving-with-repr-packed-no-clone-suggestion.stderr new file mode 100644 index 0000000000000..777661bcc252e --- /dev/null +++ b/tests/ui/derives/deriving-with-repr-packed-no-clone-suggestion.stderr @@ -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`.