about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs24
-rw-r--r--tests/ui/macros/auxiliary/borrowck-error-in-macro.rs10
-rw-r--r--tests/ui/macros/borrowck-error-in-macro.rs8
-rw-r--r--tests/ui/macros/borrowck-error-in-macro.stderr19
4 files changed, 53 insertions, 8 deletions
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 56cc4327585..a5c9bad3ac2 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -840,14 +840,22 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
             } else {
                 bug!("not an upvar")
             };
-            err.span_label(
-                *span,
-                format!(
-                    "calling `{}` requires mutable binding due to {}",
-                    self.describe_place(the_place_err).unwrap(),
-                    reason
-                ),
-            );
+            // sometimes we deliberately don't store the name of a place when coming from a macro in
+            // another crate. We generally want to limit those diagnostics a little, to hide
+            // implementation details (such as those from pin!() or format!()). In that case show a
+            // slightly different error message, or none at all if something else happened. In other
+            // cases the message is likely not useful.
+            if let Some(place_name) = self.describe_place(the_place_err) {
+                err.span_label(
+                    *span,
+                    format!("calling `{place_name}` requires mutable binding due to {reason}"),
+                );
+            } else if span.from_expansion() {
+                err.span_label(
+                    *span,
+                    format!("a call in this macro requires a mutable binding due to {reason}",),
+                );
+            }
         }
     }
 
diff --git a/tests/ui/macros/auxiliary/borrowck-error-in-macro.rs b/tests/ui/macros/auxiliary/borrowck-error-in-macro.rs
new file mode 100644
index 00000000000..2d5f2bda2ed
--- /dev/null
+++ b/tests/ui/macros/auxiliary/borrowck-error-in-macro.rs
@@ -0,0 +1,10 @@
+#[macro_export]
+macro_rules! ice {
+    () => {
+        fn main() {
+            let d = &mut 0;
+            let c = || *d += 1;
+            c();
+        }
+    };
+}
diff --git a/tests/ui/macros/borrowck-error-in-macro.rs b/tests/ui/macros/borrowck-error-in-macro.rs
new file mode 100644
index 00000000000..fe75188efd2
--- /dev/null
+++ b/tests/ui/macros/borrowck-error-in-macro.rs
@@ -0,0 +1,8 @@
+//@ aux-build: borrowck-error-in-macro.rs
+//@ error-pattern: a call in this macro requires a mutable binding due to mutable borrow of `d`
+//FIXME: remove error-pattern (see #141896)
+
+extern crate borrowck_error_in_macro as a;
+
+a::ice! {}
+//~^ ERROR cannot borrow value as mutable, as it is not declared as mutable
diff --git a/tests/ui/macros/borrowck-error-in-macro.stderr b/tests/ui/macros/borrowck-error-in-macro.stderr
new file mode 100644
index 00000000000..ec0302ee287
--- /dev/null
+++ b/tests/ui/macros/borrowck-error-in-macro.stderr
@@ -0,0 +1,19 @@
+error[E0596]: cannot borrow value as mutable, as it is not declared as mutable
+  --> $DIR/borrowck-error-in-macro.rs:7:1
+   |
+LL | a::ice! {}
+   | ^^^^^^^^^^
+   | |
+   | cannot borrow as mutable
+   | a call in this macro requires a mutable binding due to mutable borrow of `d`
+   |
+   = note: this error originates in the macro `a::ice` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider changing this to be mutable
+  --> $DIR/auxiliary/borrowck-error-in-macro.rs:6:17
+   |
+LL |             let mut c = || *d += 1;
+   |                 +++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0596`.