about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthew Jasper <mjjasper1@gmail.com>2019-05-03 22:24:52 +0100
committerMatthew Jasper <mjjasper1@gmail.com>2019-05-21 20:38:17 +0100
commitebd6c7164ee7d8f85a640858f1cad1f56cc11a35 (patch)
tree738f14c3e130e1678442d2b626dcabba18b44439
parent50a0defd5a93523067ef239936cc2e0755220904 (diff)
downloadrust-ebd6c7164ee7d8f85a640858f1cad1f56cc11a35.tar.gz
rust-ebd6c7164ee7d8f85a640858f1cad1f56cc11a35.zip
Dont show variables from desugarings in borrowck errors
-rw-r--r--src/librustc/mir/mod.rs7
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs8
-rw-r--r--src/librustc_mir/borrow_check/mutability_errors.rs47
-rw-r--r--src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs4
-rw-r--r--src/libsyntax/parse/parser.rs9
-rw-r--r--src/test/ui/nll/dont-print-desugared-async.rs9
-rw-r--r--src/test/ui/nll/dont-print-desugared-async.stderr12
-rw-r--r--src/test/ui/nll/dont-print-desugared.rs21
-rw-r--r--src/test/ui/nll/dont-print-desugared.stderr27
9 files changed, 112 insertions, 32 deletions
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index dd43cb2f18e..aab9d5e3a02 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -915,6 +915,13 @@ impl<'tcx> LocalDecl<'tcx> {
         }
     }
 
+    /// Returns `true` is the local is from a compiler desugaring, e.g.,
+    /// `__next` from a `for` loop.
+    #[inline]
+    pub fn from_compiler_desugaring(&self) -> bool {
+        self.source_info.span.compiler_desugaring_kind().is_some()
+    }
+
     /// Creates a new `LocalDecl` for a temporary.
     #[inline]
     pub fn new_temp(ty: Ty<'tcx>, span: Span) -> Self {
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 1a1000f0bb4..d7841807624 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -1760,15 +1760,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
     }
 
     /// Appends end-user visible description of the `local` place to `buf`. If `local` doesn't have
-    /// a name, then `Err` is returned
+    /// a name, or its name was generated by the compiler, then `Err` is returned
     fn append_local_to_string(&self, local_index: Local, buf: &mut String) -> Result<(), ()> {
         let local = &self.mir.local_decls[local_index];
         match local.name {
-            Some(name) => {
-                buf.push_str(&name.to_string());
+            Some(name) if !local.from_compiler_desugaring() => {
+                buf.push_str(name.as_str().get());
                 Ok(())
             }
-            None => Err(()),
+            _ => Err(()),
         }
     }
 
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 32088ff9f61..f0b4efe2630 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -420,28 +420,31 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                     );
                 }
 
-                if let Some(name) = local_decl.name {
-                    err.span_label(
-                        span,
-                        format!(
-                            "`{NAME}` is a `{SIGIL}` {DESC}, \
-                             so the data it refers to cannot be {ACTED_ON}",
-                            NAME = name,
-                            SIGIL = pointer_sigil,
-                            DESC = pointer_desc,
-                            ACTED_ON = acted_on
-                        ),
-                    );
-                } else {
-                    err.span_label(
-                        span,
-                        format!(
-                            "cannot {ACT} through `{SIGIL}` {DESC}",
-                            ACT = act,
-                            SIGIL = pointer_sigil,
-                            DESC = pointer_desc
-                        ),
-                    );
+                match local_decl.name {
+                    Some(name) if !local_decl.from_compiler_desugaring() => {
+                        err.span_label(
+                            span,
+                            format!(
+                                "`{NAME}` is a `{SIGIL}` {DESC}, \
+                                so the data it refers to cannot be {ACTED_ON}",
+                                NAME = name,
+                                SIGIL = pointer_sigil,
+                                DESC = pointer_desc,
+                                ACTED_ON = acted_on
+                            ),
+                        );
+                    }
+                    _ => {
+                        err.span_label(
+                            span,
+                            format!(
+                                "cannot {ACT} through `{SIGIL}` {DESC}",
+                                ACT = act,
+                                SIGIL = pointer_sigil,
+                                DESC = pointer_desc
+                            ),
+                        );
+                    }
                 }
             }
 
diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
index 35efc6195be..6bca470bf3e 100644
--- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs
@@ -112,7 +112,7 @@ impl BorrowExplanation {
                 };
 
                 match local_decl.name {
-                    Some(local_name) => {
+                    Some(local_name) if !local_decl.from_compiler_desugaring() => {
                         let message = format!(
                             "{B}borrow might be used here, when `{LOC}` is dropped \
                              and runs the {DTOR} for {TYPE}",
@@ -130,7 +130,7 @@ impl BorrowExplanation {
                             );
                         }
                     }
-                    None => {
+                    _ => {
                         err.span_label(
                             local_decl.source_info.span,
                             format!(
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 24d120376de..8083e00f607 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -8423,6 +8423,8 @@ impl<'a> Parser<'a> {
             for (index, input) in decl.inputs.iter_mut().enumerate() {
                 let id = ast::DUMMY_NODE_ID;
                 let span = input.pat.span;
+                let desugared_span = self.sess.source_map()
+                    .mark_span_with_reason(CompilerDesugaringKind::Async, span, None);
 
                 // Construct a name for our temporary argument.
                 let name = format!("__arg{}", index);
@@ -8439,8 +8441,7 @@ impl<'a> Parser<'a> {
                         // this would affect the input to procedural macros, but they can have
                         // their span marked as being the result of a compiler desugaring so
                         // that they aren't linted against.
-                        input.pat.span = self.sess.source_map().mark_span_with_reason(
-                            CompilerDesugaringKind::Async, span, None);
+                        input.pat.span = desugared_span;
 
                         (binding_mode, ident, true)
                     }
@@ -8460,7 +8461,7 @@ impl<'a> Parser<'a> {
                             node: PatKind::Ident(
                                 BindingMode::ByValue(Mutability::Immutable), ident, None,
                             ),
-                            span,
+                            span: desugared_span,
                         }),
                         source: ArgSource::AsyncFn(input.pat.clone()),
                     })
@@ -8473,7 +8474,7 @@ impl<'a> Parser<'a> {
                     pat: P(Pat {
                         id,
                         node: PatKind::Ident(binding_mode, ident, None),
-                        span,
+                        span: desugared_span,
                     }),
                     // We explicitly do not specify the type for this statement. When the user's
                     // argument type is `impl Trait` then this would require the
diff --git a/src/test/ui/nll/dont-print-desugared-async.rs b/src/test/ui/nll/dont-print-desugared-async.rs
new file mode 100644
index 00000000000..8150a260866
--- /dev/null
+++ b/src/test/ui/nll/dont-print-desugared-async.rs
@@ -0,0 +1,9 @@
+// Test that we don't show variables with from async fn desugaring
+
+// edition:2018
+#![feature(async_await)]
+
+async fn async_fn(&ref mut s: &[i32]) {}
+//~^ ERROR cannot borrow data in a `&` reference as mutable [E0596]
+
+fn main() {}
diff --git a/src/test/ui/nll/dont-print-desugared-async.stderr b/src/test/ui/nll/dont-print-desugared-async.stderr
new file mode 100644
index 00000000000..47726ba65df
--- /dev/null
+++ b/src/test/ui/nll/dont-print-desugared-async.stderr
@@ -0,0 +1,12 @@
+error[E0596]: cannot borrow data in a `&` reference as mutable
+  --> $DIR/dont-print-desugared-async.rs:6:20
+   |
+LL | async fn async_fn(&ref mut s: &[i32]) {}
+   |                   -^^^^^^^^^
+   |                   ||
+   |                   |cannot borrow as mutable through `&` reference
+   |                   help: consider changing this to be a mutable reference: `&mut ref mut s`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0596`.
diff --git a/src/test/ui/nll/dont-print-desugared.rs b/src/test/ui/nll/dont-print-desugared.rs
new file mode 100644
index 00000000000..829d78ed4c3
--- /dev/null
+++ b/src/test/ui/nll/dont-print-desugared.rs
@@ -0,0 +1,21 @@
+// Test that we don't show variables with from for loop desugaring
+
+fn for_loop(s: &[i32]) {
+    for &ref mut x in s {}
+    //~^ ERROR cannot borrow data in a `&` reference as mutable [E0596]
+}
+
+struct D<'a>(&'a ());
+
+impl Drop for D<'_> {
+    fn drop(&mut self) {}
+}
+
+fn for_loop_dropck(v: Vec<D<'static>>) {
+    for ref mut d in v {
+        let y = ();
+        *d = D(&y); //~ ERROR `y` does not live long enough
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/dont-print-desugared.stderr b/src/test/ui/nll/dont-print-desugared.stderr
new file mode 100644
index 00000000000..45d7cbcdfbe
--- /dev/null
+++ b/src/test/ui/nll/dont-print-desugared.stderr
@@ -0,0 +1,27 @@
+error[E0596]: cannot borrow data in a `&` reference as mutable
+  --> $DIR/dont-print-desugared.rs:4:10
+   |
+LL |     for &ref mut x in s {}
+   |         -^^^^^^^^^
+   |         ||
+   |         |cannot borrow as mutable through `&` reference
+   |         help: consider changing this to be a mutable reference: `&mut ref mut x`
+
+error[E0597]: `y` does not live long enough
+  --> $DIR/dont-print-desugared.rs:17:16
+   |
+LL |     for ref mut d in v {
+   |                      - a temporary with access to the borrow is created here ...
+LL |         let y = ();
+LL |         *d = D(&y);
+   |                ^^ borrowed value does not live long enough
+LL |     }
+   |     -
+   |     |
+   |     `y` dropped here while still borrowed
+   |     ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `D`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0596, E0597.
+For more information about an error, try `rustc --explain E0596`.