diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl index bf14d5eb9a0..f2ca509e14b 100644 --- a/compiler/rustc_borrowck/messages.ftl +++ b/compiler/rustc_borrowck/messages.ftl @@ -16,6 +16,9 @@ borrowck_borrow_due_to_use_closure = borrowck_borrow_due_to_use_coroutine = borrow occurs due to use in coroutine +borrowck_calling_operator_moves = + calling this operator moves the value + borrowck_calling_operator_moves_lhs = calling this operator moves the left-hand side diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 4ebbe592628..914f68a38b4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -1050,7 +1050,7 @@ fn explain_captures( ); err.subdiagnostic(self.dcx(), CaptureReasonNote::FnOnceMoveInCall { var_span }); } - CallKind::Operator { self_arg, .. } => { + CallKind::Operator { self_arg, trait_id, .. } => { let self_arg = self_arg.unwrap(); err.subdiagnostic( self.dcx(), @@ -1062,9 +1062,16 @@ fn explain_captures( }, ); if self.fn_self_span_reported.insert(fn_span) { + let lang = self.infcx.tcx.lang_items(); err.subdiagnostic( self.dcx(), - CaptureReasonNote::LhsMoveByOperator { span: self_arg.span }, + if [lang.not_trait(), lang.deref_trait(), lang.neg_trait()] + .contains(&Some(trait_id)) + { + CaptureReasonNote::UnOpMoveByOperator { span: self_arg.span } + } else { + CaptureReasonNote::LhsMoveByOperator { span: self_arg.span } + }, ); } } diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs index a055ce95e8e..77021ae4321 100644 --- a/compiler/rustc_borrowck/src/session_diagnostics.rs +++ b/compiler/rustc_borrowck/src/session_diagnostics.rs @@ -368,6 +368,11 @@ pub(crate) enum CaptureReasonNote { #[primary_span] var_span: Span, }, + #[note(borrowck_calling_operator_moves)] + UnOpMoveByOperator { + #[primary_span] + span: Span, + }, #[note(borrowck_calling_operator_moves_lhs)] LhsMoveByOperator { #[primary_span] diff --git a/tests/ui/unop-move-semantics.stderr b/tests/ui/unop-move-semantics.stderr index b6de7976ac9..187dd66b2fe 100644 --- a/tests/ui/unop-move-semantics.stderr +++ b/tests/ui/unop-move-semantics.stderr @@ -9,7 +9,7 @@ LL | LL | x.clone(); | ^ value borrowed here after move | -note: calling this operator moves the left-hand side +note: calling this operator moves the value --> $SRC_DIR/core/src/ops/bit.rs:LL:COL help: consider cloning the value if the performance cost is acceptable | @@ -57,7 +57,7 @@ LL | !*m; | |move occurs because `*m` has type `T`, which does not implement the `Copy` trait | `*m` moved due to usage in operator | -note: calling this operator moves the left-hand side +note: calling this operator moves the value --> $SRC_DIR/core/src/ops/bit.rs:LL:COL error[E0507]: cannot move out of `*n` which is behind a shared reference