From 306dcd6efa72c5f06c0f62ac90618d1f60cd7000 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Sat, 19 Mar 2022 15:48:39 -0700 Subject: [PATCH] diagnostics: do not give Option::as_ref suggestion for complex match Fixes #82528 --- .../src/diagnostics/move_errors.rs | 24 +++++++++++++++---- .../option-content-move-from-tuple-match.rs | 9 +++++++ ...ption-content-move-from-tuple-match.stderr | 15 ++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/suggestions/option-content-move-from-tuple-match.rs create mode 100644 src/test/ui/suggestions/option-content-move-from-tuple-match.stderr diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 48a70abc0b6..a58c788eb57 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -218,18 +218,29 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fn report(&mut self, error: GroupedMoveError<'tcx>) { let (mut err, err_span) = { - let (span, use_spans, original_path, kind): ( + let (span, use_spans, original_path, kind, has_complex_bindings): ( Span, Option>, Place<'tcx>, &IllegalMoveOriginKind<'_>, + bool, ) = match error { - GroupedMoveError::MovesFromPlace { span, original_path, ref kind, .. } - | GroupedMoveError::MovesFromValue { span, original_path, ref kind, .. } => { - (span, None, original_path, kind) + GroupedMoveError::MovesFromPlace { + span, + original_path, + ref kind, + ref binds_to, + .. } + | GroupedMoveError::MovesFromValue { + span, + original_path, + ref kind, + ref binds_to, + .. + } => (span, None, original_path, kind, !binds_to.is_empty()), GroupedMoveError::OtherIllegalMove { use_spans, original_path, ref kind } => { - (use_spans.args_or_use(), Some(use_spans), original_path, kind) + (use_spans.args_or_use(), Some(use_spans), original_path, kind, false) } }; debug!( @@ -248,6 +259,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { target_place, span, use_spans, + has_complex_bindings, ), &IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => { self.cannot_move_out_of_interior_of_drop(span, ty) @@ -290,6 +302,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { deref_target_place: Place<'tcx>, span: Span, use_spans: Option>, + has_complex_bindings: bool, ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { // Inspect the type of the content behind the // borrow to provide feedback about why this @@ -399,6 +412,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let diag_name = self.infcx.tcx.get_diagnostic_name(def_id); if matches!(diag_name, Some(sym::Option | sym::Result)) && use_spans.map_or(true, |v| !v.for_closure()) + && !has_complex_bindings { err.span_suggestion_verbose( span.shrink_to_hi(), diff --git a/src/test/ui/suggestions/option-content-move-from-tuple-match.rs b/src/test/ui/suggestions/option-content-move-from-tuple-match.rs new file mode 100644 index 00000000000..7f22d81360b --- /dev/null +++ b/src/test/ui/suggestions/option-content-move-from-tuple-match.rs @@ -0,0 +1,9 @@ +fn foo(a: &Option, b: &Option) { + match (a, b) { + //~^ ERROR cannot move out of a shared reference + (None, &c) => &c.unwrap(), + (&Some(ref c), _) => c, + }; +} + +fn main() {} diff --git a/src/test/ui/suggestions/option-content-move-from-tuple-match.stderr b/src/test/ui/suggestions/option-content-move-from-tuple-match.stderr new file mode 100644 index 00000000000..debb8cabaea --- /dev/null +++ b/src/test/ui/suggestions/option-content-move-from-tuple-match.stderr @@ -0,0 +1,15 @@ +error[E0507]: cannot move out of a shared reference + --> $DIR/option-content-move-from-tuple-match.rs:2:11 + | +LL | match (a, b) { + | ^^^^^^ +LL | +LL | (None, &c) => &c.unwrap(), + | - + | | + | data moved here + | move occurs because `c` has type `Option`, which does not implement the `Copy` trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`.