about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2019-12-11 23:04:29 +0900
committerYuki Okushi <huyuumi.dev@gmail.com>2019-12-12 11:13:13 +0900
commitfa199c5f27cf09fa02ff7632a713ea613f731944 (patch)
treec149b12b4369fec714d85fcf026475b30460f0d5 /src
parent27d6f55f47e8875e71083a28ed84ea5a88e1b596 (diff)
downloadrust-fa199c5f27cf09fa02ff7632a713ea613f731944.tar.gz
rust-fa199c5f27cf09fa02ff7632a713ea613f731944.zip
Don't suggest wrong snippet in closure
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/move_errors.rs16
-rw-r--r--src/test/ui/suggestions/option-content-move2.rs16
-rw-r--r--src/test/ui/suggestions/option-content-move2.stderr18
3 files changed, 46 insertions, 4 deletions
diff --git a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs
index 938836db9ae..cc634101f0a 100644
--- a/src/librustc_mir/borrow_check/diagnostics/move_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/move_errors.rs
@@ -223,18 +223,24 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
     fn report(&mut self, error: GroupedMoveError<'tcx>) {
         let (mut err, err_span) = {
-            let (span, original_path, kind): (Span, &Place<'tcx>, &IllegalMoveOriginKind<'_>) =
+            let (span, use_spans, original_path, kind,):
+            (
+                Span,
+                Option<UseSpans>,
+                &Place<'tcx>,
+                &IllegalMoveOriginKind<'_>,
+            ) =
                 match error {
                     GroupedMoveError::MovesFromPlace { span, ref original_path, ref kind, .. } |
                     GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } => {
-                        (span, original_path, kind)
+                        (span, None, original_path, kind)
                     }
                     GroupedMoveError::OtherIllegalMove {
                         use_spans,
                         ref original_path,
                         ref kind
                     } => {
-                        (use_spans.args_or_use(), original_path, kind)
+                        (use_spans.args_or_use(), Some(use_spans), original_path, kind)
                     },
                 };
             debug!("report: original_path={:?} span={:?}, kind={:?} \
@@ -250,6 +256,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                             original_path,
                             target_place,
                             span,
+                            use_spans,
                         )
                     }
                     IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
@@ -296,6 +303,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         move_place: &Place<'tcx>,
         deref_target_place: &Place<'tcx>,
         span: Span,
+        use_spans: Option<UseSpans>,
     ) -> DiagnosticBuilder<'a> {
         // Inspect the type of the content behind the
         // borrow to provide feedback about why this
@@ -416,7 +424,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) {
             let is_option = move_ty.starts_with("std::option::Option");
             let is_result = move_ty.starts_with("std::result::Result");
-            if is_option || is_result {
+            if (is_option || is_result) && use_spans.map_or(true, |v| !v.for_closure()) {
                 err.span_suggestion(
                     span,
                     &format!("consider borrowing the `{}`'s content", if is_option {
diff --git a/src/test/ui/suggestions/option-content-move2.rs b/src/test/ui/suggestions/option-content-move2.rs
new file mode 100644
index 00000000000..88e8a5b7aee
--- /dev/null
+++ b/src/test/ui/suggestions/option-content-move2.rs
@@ -0,0 +1,16 @@
+struct NotCopyable;
+
+fn func<F: FnMut() -> H, H: FnMut()>(_: F) {}
+
+fn parse() {
+    let mut var = None;
+    func(|| {
+        // Shouldn't suggest `move ||.as_ref()` here
+        move || {
+        //~^ ERROR: cannot move out of `var`
+            var = Some(NotCopyable);
+        }
+    });
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/option-content-move2.stderr b/src/test/ui/suggestions/option-content-move2.stderr
new file mode 100644
index 00000000000..71f745374e5
--- /dev/null
+++ b/src/test/ui/suggestions/option-content-move2.stderr
@@ -0,0 +1,18 @@
+error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
+  --> $DIR/option-content-move2.rs:9:9
+   |
+LL |     let mut var = None;
+   |         ------- captured outer variable
+...
+LL |         move || {
+   |         ^^^^^^^ move out of `var` occurs here
+LL |
+LL |             var = Some(NotCopyable);
+   |             ---
+   |             |
+   |             move occurs because `var` has type `std::option::Option<NotCopyable>`, which does not implement the `Copy` trait
+   |             move occurs due to use in closure
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.