about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Howell <michael@notriddle.com>2022-03-19 15:48:39 -0700
committerMichael Howell <michael@notriddle.com>2022-03-19 15:54:30 -0700
commit306dcd6efa72c5f06c0f62ac90618d1f60cd7000 (patch)
tree32a23becb56bf87d1050ff2cb71b78d6e92c75af
parent9b701e7eaa08c2b2ef8c6e59b8b33436cb10aa45 (diff)
downloadrust-306dcd6efa72c5f06c0f62ac90618d1f60cd7000.tar.gz
rust-306dcd6efa72c5f06c0f62ac90618d1f60cd7000.zip
diagnostics: do not give Option::as_ref suggestion for complex match
Fixes #82528
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs24
-rw-r--r--src/test/ui/suggestions/option-content-move-from-tuple-match.rs9
-rw-r--r--src/test/ui/suggestions/option-content-move-from-tuple-match.stderr15
3 files changed, 43 insertions, 5 deletions
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<UseSpans<'tcx>>,
                 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<UseSpans<'tcx>>,
+        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<String>, b: &Option<String>) {
+    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<String>`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.